` 如何在使用Neo4j Python Driver时将标签设置为变量的Cypher查询

2024-09-30 22:14:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将Label和Relationship设置为cypher查询中的一个变量,因为我不想逐个列出所有的Label并为它们创建cypher查询。你知道吗

我就是这么做的:

class Neo4jClient(object):
    def __init__(self, uri, user, password):
        self._driver = GraphDatabase.driver(uri, auth=basic_auth(user, password))
    def close(self):
        self._driver.close()
    def merge_nodes_relationships(self, anchor_data):
        event = anchor_data.event
        anchor = anchor_data.anchor
        for k, v in anchor.items():
            relation = session.write_transaction(self.create_event_anchor_relation, event, k, v)
    @staticmethod
    def create_event_anchor_relation(tx, event, anchorkey, anchorvalue):
        result =  tx.run("MATCH(e: Event {id : $eventid}), (a: $Anchor {id:$anchorvalue)"
                         "MERGE(e)-[r:$RelationShip]-(a)"
                         "RETURN r", eventid=event['id'], Anchor=anchorkey, anchorvalue=anchorvalue, RelationShip='EVENT_' + anchorkey
                         )
        return result.single()[0]

但是错误抛出说

无效输入“$”:需要空白或标签名(第1行,第10列(偏移量:9))\n\“MERGE(a:$Anchor{id:$id})\”\n

那我该怎么解决呢?如果不支持参数化标签或关系,那么处理具有相同属性但需要不同标签名称的多个标签时的最佳做法是什么。你知道吗


Tags: selfeventiddatadefdriver标签uri
1条回答
网友
1楼 · 发布于 2024-09-30 22:14:38

通常应避免这种情况,但以下方法可行:

MATCH (e :Event {id: $eventid}), (a {id: $anchorvalue)
WHERE $Anchor IN LABELS(a)
MERGE(e)-[r]-(a)
WHERE $RelationShip IN LABELS(r)
RETURN r

编辑:要查看这是错误的原因,请运行以下两个查询:

PROFILE
MATCH (e :Event)
RETURN e

以及

PROFILE
MATCH (e)
WHERE "Event" IN LABELS(e)
RETURN e

请注意,它们实际上返回相同的东西,但它们以非常不同的方式返回。你知道吗

第一个运行一个NodeByLabelScan,它快速查找标签为“Event”的所有节点。由于Neo4j是如何存储这些数据的,所以这些节点“存储在一起”,并且查找起来非常快。你知道吗

第二个查询运行AllNodesScan,然后运行Filter。以这种方式,必须检查数据库中的每个节点,看它是否有“Event”作为标签。你知道吗

一般来说,如果您使用标签作为变量,那么您没有为数据选择一个非常好的结构。你知道吗

相关问题 更多 >