如何使用Cypher删除两个节点之间的重复关系?

25

当我运行这个查询:

START n1=node(7727), n2=node(7730)
MATCH n1-[r:SKILL]->n2 RETURN r

它给我列出了两个节点之间的重复关系列表。我应该在Cypher查询中添加什么来遍历这些关系,保留一条关系并删除其他重复的关系?

4个回答

42
为了实现两个已知节点之间的操作,请按照以下步骤进行:
start n=node(1), m=node(2) match (n)-[r]->(m) 
with n,m,type(r) as t, tail(collect(r)) as coll 
foreach(x in coll | delete x)

如果要全局应用到所有关系(请注意,这个操作可能会非常耗时,具体时间取决于您的图形大小):

start r=relationship(*) 
match (s)-[r]->(e)
with s,e,type(r) as typ, tail(collect(r)) as coll 
foreach(x in coll | delete x)

2
在最近的neo4j版本中,我相信START子句是不必要的,对吧?它似乎没有使用它也能正常工作。 - Ken Williams
3
直到我意识到 tail 返回除第一个元素外的所有元素,我才明白这是如何工作的。谢谢! - fiat
我在想你从哪里找到了你使用的“relationship”函数? 我在文档中没有看到它,只有“relationships”。这是一个旧的函数吗? - pooshla
2
这个已经很久以前被移除了。现在你只需要省略第一行,直接用“match”开始语句即可。 - Stefan Armbruster

7

使用Neo4J 4.x来全局删除重复关系,您需要使用以下方法。语法略有变化,另一个回答中提到的start前缀不再可用。

match ()-[r]->() 
match (s)-[r]->(e) 
with s,e,type(r) as typ, tail(collect(r)) as coll 
foreach(x in coll | delete x)

1
匹配() - [r] ->() - plastic
为什么不使用match ()-[r:RELTYPE]-() with type(r) as typ, tail(collect(r)) as coll foreach(x in coll | delete x);来删除关系?为什么它会删除所有该类型的关系? - Ooker

4
如果您对随机的查询删除数据库中的数据存在信任问题,您可以像我一样做以下操作。
首先,您可能会想检查所选的关系是否真的是重复的。这个查询将设置一个属性 willBeDeleted 为 true,因此您可以检查自己是否真的想要删除它们。
match (a)-[r]->(b) 
with a,b,type(r) as typ, tail(collect(r)) as coll 
foreach(x in coll | set x.willBeDeleted=true)

现在你可以检查哪些关系实际上将被删除。
match(a)-[r]-(b)
where r.willBeDeleted=true
return a, b, r

如果您认为正确的关系将被删除,那么可以执行此查询以删除重复项。

match (a)-[r]->(b) 
with a,b,type(r) as typ, tail(collect(r)) as coll 
foreach(x in coll | delete x)

0

这里有一个很好的方法来查找所有重复的关系并获得一些可见性,以了解它们发生的位置。

MATCH p=(n)-[r1]->(g)<-[r2]-(n)
WHERE type(r1) = type(r2) AND r1 <> r2
RETURN type(r1) as relType, labels(n), labels(g), count(p)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接