美文网首页
使用cypher语句根据结点属性删除相同结点及其关系

使用cypher语句根据结点属性删除相同结点及其关系

作者: 今天无Bug | 来源:发表于2019-03-20 22:06 被阅读0次

原文链接: https://gist.github.com/jruts/fe782ff2531d509784a24b655ad8ae76

这个问题很好理解,在数据库中有id相同的结点存在。

这事看上去挺简单,但当真真做时才知道,并没有想的那么容易。

第一步

我首先尝试着找出重复的结点,这个看上去很简单。

MATCH (g:geo) 
WITH g.id as id, collect(g) AS nodes
WHERE size(nodes) > 1
RETURN nodes

这个查询得到所有geo标签的结点,然后创建id属性个数大于1的结点列表。
这个查询结果就是得到重复的带有geo标签的结点列表。示例结果如下:

nodesgeo:123, geo:123geo: 578, geo: 578, geo:578

第二步

接下来我要尝试着删除重复的,当然要留一个。

MATCH (g:geo) 
WITH g.id as id, collect(g) AS nodes
WHERE size(nodes) > 1
FOREACH (g in tail(nodes) | DELETE g)

这个语句会出错:

org.neo4j.kernel.api.exceptions.ConstraintViolationTransactionFailureException: Cannot delete node<866>, because it still has relationships. To delete this node, you must first delete its relationships.

看上去我们好像快要搞定了,但是我先解释一下这个查询。
我们使用之前相应的查询,但是我们没有返回结点,而是遍历 tail(nodes) 的结点,依次删除这些结点。

tail 函数能够返回一个列表中除了首结点之外的所有结点,所以,我们能确保有一个结点不被删除。

第三步

上面的错误显示,我们在删除结点之前需要先删除他们关系。 

MATCH (g:geo) 
WITH g.id as id, collect(g) AS nodes
WHERE size(nodes) > 1
UNWIND tail(nodes) as tails
MATCH (tails)-[r]-()
DELETE r

重复的结点的关系被成功删除了,当我们再次运行第二步的语句时,重复的结点也被删除了。

解决方案

先删除重复结点的重复关系 

MATCH (g:geo) 
WITH g.id as id, collect(g) AS nodes
WHERE size(nodes) > 1
UNWIND tail(nodes) as tails
MATCH (tails)-[r]-()
DELETE r

再删除重复的结点 

MATCH (g:geo) 
WITH g.id as id, collect(g) AS nodes
WHERE size(nodes) > 1
FOREACH (g in tail(nodes) | DELETE g)

希望这些能帮助到大家。

译者言:事实上有更简单的方法,一步完成这种删除。

MATCH (g:geo)
WITH g.id as id, collect(g) AS nodes
WHERE size(nodes) > 1
FOREACH (g in tail(nodes) | DETACH DELETE g)

相关文章

网友评论

      本文标题:使用cypher语句根据结点属性删除相同结点及其关系

      本文链接:https://www.haomeiwen.com/subject/rzyxvqtx.html