合并Neo4j中的节点

时间:2018-05-18 10:42:11

标签: neo4j cypher

我有一个具有以下模式的XML文件:具有 ref 属性的节点与其他节点的 id 属性具有相同的值。 这是Neo4j的一个直观的例子:

Sample data set

黄色的ref属性(ref = 2)值为 TWO (id = 2)。

我的目标是创建一个图表,删除每个节点的ref值等于其他id节点,同时保留必须指向另一个节点的 isFatherOf 关系,在此case, TWO

以下是该程序的结果:

Desired output

我可以使用以下步骤删除所有ref节点,

match (n1:Node)
with collect(distinct n1.id) as ids 
collection called 'ids'
match (n2:Node)
where n2.ref in ids
detach delete n2

但我不知道如何保持这种关系。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:1)

我使用此示例数据模型重现了您的场景:

create (one:Node {id : 1, name : 'ONE'}),
    (two:Node {id : 2, name : 'TWO'}),
    (ref:Node {ref:2}),
    (one)-[:isFatherOf]->(ref)

以下Cypher查询应该做的工作:

// get all 'n1' nodes point to an node with 'ref' property
match (n1:Node)-[r:isFatherOf]->(refNode:Node)
where exists(refNode.ref)
// match 'n2' nodes that have an ID equal to 'n2.ref'
match (n2:Node {id : refNode.ref})
// create a new relationship between 'n1' and 'n2'
create (n1)-[:isFatherOf]->(n2)
// remove node with 'ref' properties and all relationships
detach delete refNode

对于样本数据集,输出将为:

Output

如果您需要保留原始关系而不是创建全新关系,则需要使用APOC Procedure apoc.refactor.to。此过程重定向关系以使用新的终端节点。

match (n1:Node)-[r:isFatherOf]->(refNode:Node)
where exists(refNode.ref)
match (n2:Node {id : refNode.ref})
// redirecting 'r' to use 'n2' as end node
call apoc.refactor.to(r, n2) yield output
delete refNode

输出结果相同。