我试图将标签和关系设置为密码查询中的变量,因为我不想一一列出所有标签并为所有标签创建密码查询。
这就是我所做的:
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]
Run Code Online (Sandbox Code Playgroud)
但错误抛出说
输入“$”无效:预期的空格或标签名称(第 1 行,第 10 列(偏移量:9))\n\"MERGE (a:$Anchor {id : $id})\"\n
那么我应该如何解决这个问题呢?如果不支持参数化标签或关系,当出现许多具有相同属性但需要不同标签名称的标签时,处理这种情况的最佳实践是什么。
通常应该避免这种情况,但以下方法会起作用:
MATCH (e :Event {id: $eventid}), (a {id: $anchorvalue)
WHERE $Anchor IN LABELS(a)
MERGE(e)-[r]-(a)
WHERE $RelationShip IN LABELS(r)
RETURN r
Run Code Online (Sandbox Code Playgroud)
编辑:要了解为什么这是不好的,请运行以下两个查询:
PROFILE
MATCH (e :Event)
RETURN e
Run Code Online (Sandbox Code Playgroud)
和
PROFILE
MATCH (e)
WHERE "Event" IN LABELS(e)
RETURN e
Run Code Online (Sandbox Code Playgroud)
请注意,它们实际上返回相同的内容,但它们以非常不同的方式执行。
第一个运行NodeByLabelScan
快速查找带有标签“Event”的所有节点。由于 Neo4j 存储这些数据的方式,这些节点“存储在一起”并且查找起来非常快。
运行第二个查询AllNodesScan
,然后运行Filter
. 通过这种方式,必须检查数据库中的每个节点以查看其是否具有“事件”作为标签。
一般来说,如果您使用标签作为变量,则说明您没有为数据选择非常好的结构。
归档时间: |
|
查看次数: |
1281 次 |
最近记录: |