我想计算“一个节点连接到另一个节点的次数”。
在两个相同的节点之间有多个冗余关系似乎不是一个好主意,因此我认为应该使用一个带有“count”属性的关系来实现这个目的。
但是如何更新这些关系并增加属性“计数”呢?
Neo4j没有任何属性的自动递增功能(根据我所读到的)。
作为一种替代方法,我想在Python中MATCH现有的关系(如果它存在的话),然后更新它的count属性,但是似乎没有任何效果。
以下是我目前所掌握的情况:
def create_or_increment_relationship(tx, start_node_label, start_node_property, new_node_label, new_node_property, relationship_type):
return tx.run(
"MATCH (s) WHERE (s.label = $start_node_label AND s.name = $start_node_property) \n \
CALL apoc.merge.node($new_node_label, {name: $new_node_property}) \n \
MATCH (s)-[r:$relationship_type]->(n) \n \
CALL apoc.merge.relationship(s, $relationship_type, r.count+1, n);",
start_node_label=start_node_label,
start_node_property=start_node_property,
new_node_label=new_node_label,
new_node_property=new_node_property,
relationship_type=relationship_type,
).single().value()
上面的查询(绿色)有4行:
- 查找start_node(s,应该已经存在)
- 查找或创建new_node(n,有时不存在)
- 求出它们之间的关系(r,如果n不存在,r就不存在)
- 如果存在,则将其“count”属性加1,否则将其设置为1(r.count)
我知道我还需要使用APOC来匹配一个基于运行时建立的标签(动态标签,即Python变量)的现有关系(这是本代码查询部分的第三行)。
然而,我找不到任何这样的查询的例子,或者一个apoc函数,它匹配的条件关系。
UPDATE:显然,APOC中匹配关系的一种方法是使用apoc.merge.relationship,如本文所述https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/2674:
在第二个例子中,我使用apoc.merge.node来匹配起始节点和结束节点,而没有实际创建或更改它们。我的假设是,Neo4j仍然会对这些节点进行写锁定,这会影响性能,并会由于同一节点上的死锁而阻碍优化,例如通过apoc.periodic.iterate进行并行化。
......致APOC的维护者:我同意如果有apoc.match.relationship(或node)函数就更好了。我认为这是为了API的易用性/理解性/清晰性;这张海报还说,在某些情况下,专用的实现可以带来性能优势。
1条答案
按热度按时间llycmphe1#
需要考虑的事项:
1.下面的语句在使用参数化查询时不起作用。因此,您的查询在此语句之后不返回数据。因此,在最后一行中不会创建任何关系
匹配(s)-[r:$关系类型]-〉(n)
修复:当变量是关系类型时,需要使用python进行字符串替换。
1.如果前一个MATCH语句没有返回行,则不会创建一个关系。查询将直接结束,而不运行最后一个apoc语句。
修复:在MATCH的CREATE上使用MERGE
1.此外,在您的查询中有打字错误,所以我建议您通过复制您生成的实际语句来调试密码查询,然后在neo4j控制台中运行它。
修复:查看查询的第1行和第2行。
下面是您可以使用的代码片段。
样本结果: