Neo4j Cypher: 合并重复的节点

6

我有一些重复的节点,都带有标签Tag。所谓的重复是指我有两个具有相同名称属性的节点,例如:

{ name: writing, _id: 57ec2289a90f9a2deece7e6d},
{ name: writing, _id: 57db1da737f2564f1d5fc5a1},
{ name: writing }

_id字段不再使用,因此在所有效果中,这三个节点是相同的,只是它们每个人都有不同的关系。

我想做的是:

  1. Find all duplicate nodes (check)

    MATCH (n:Tag)
    WITH n.name AS name, COLLECT(n) AS nodelist, COUNT(*) AS count
    WHERE count > 1
    RETURN name, nodelist, count
    
  2. Copy all relationships from the duplicate nodes into the first one

  3. Delete all the duplicate nodes
这可以通过cypher查询实现吗?还是我需要使用某种编程语言编写脚本?(这就是我试图避免的)
2个回答

16

APOC Procedures有一些图形重构过程,可以帮助您。我认为apoc.refactor.mergeNodes()应该能解决问题。

请注意,除了将所有关系从其他节点转移到列表中的第一个节点之外,它还会将其他节点的任何标签和属性应用到第一个节点上。如果这不是您想要做的事情,那么您可能需要收集其他节点的传入和传出关系,并使用apoc.refactor.to()apoc.refactor.from()

以下是合并节点的查询:

MATCH (n:Tag)
WITH n.name AS name, COLLECT(n) AS nodelist, COUNT(*) AS count
WHERE count > 1
CALL apoc.refactor.mergeNodes(nodelist) YIELD node
RETURN node

哇,我不知道这个apoc插件。非常有用,谢谢! - Juan Fuentes
有没有办法避免在此查询的末尾使用RETURN语句?例如,如果我只想合并数据库中的节点而不返回任何内容。 - Filippo Grazioli
目前查询必须以RETURN结尾,或者以SET、REMOVE、CREATE、DELETE和MERGE等写入子句结尾。如果您只想将返回的行数保持在1以下,可以始终返回count(*) - InverseFalcon

1
上面的密码查询在我的数据库 版本3.4.16 上没有起作用。
对我有用的是:
MATCH (n:Tag)
WITH n.name AS name, COLLECT(n) AS nodelist, COUNT(*) AS count
WHERE count > 1
CALL apoc.refactor.mergeNodes(nodelist,{
  properties:"combine",
  mergeRels:true
})
YIELD node
RETURN node; 

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