如何将一个节点的属性和关系移动到另一个节点?

时间:2016-06-23 11:18:18

标签: neo4j cypher

我在图中有两个独立的节点,在某一点上我会得到一个信号,那两个节点实际上应该是一个。所以我必须合并两者,包括他们的属性(没有重叠),我也应该保持关系。

示例图表:(d)->(a {id:1}), (b)->(c {name:"Sam"})

期望的结果:(d)->(a {id:1, name:"Sam"}), (b)->(a {id:1, name:"Sam"})

标签a实际上并非必须在结果中出现 - 重点是我们只有一个节点代表原始的两个节点。

以下合并属性。

MATCH (a:Entity {id:"1"}), (c:Entity {name:"Sam"})
SET a += c

但我似乎无法找到移动/复制关系的方法。

规格:

  • 这两个节点不具备相同的属性
  • 节点a 可能具有传入和传出关系
  • 节点c 可能有传入关系,非传出

有什么想法吗?

更新

以下工作,假设提前到达节点c的类型和属性。我可以改进它以使其更具动态性吗?

MATCH (a:Entity {id1:"1"}), (c:Entity {id2:"2"})
SET a += c
WITH a, c
MATCH (c)<-[r]-(b)
WITH a, c, r, b
MERGE (b)-[:REL_NAME {prop1:r.prop1, prop2:r.prop2}]->(a)
WITH c
DETACH DELETE c

更新2: 上述情况有时会引发unable to load relationship with id错误,我不确定原因,但它似乎与读/写同时有关。

更新3: 这是解决错误的方法:

MATCH (a:Entity {id1:"1"}), (c:Entity {id2:"2"})
SET a += c
WITH a, c
MATCH (c)<-[r]-(b)
WITH a, c, r, b
MERGE (b)-[r2:REL_NAME]->(a)
SET r2 += r
WITH r, c
DELETE r, c

1 个答案:

答案 0 :(得分:1)

移动节点之间关系时的问题是您无法动态设置关系类型。

因此,您无法MATCH来自节点c的所有关系,并在节点a上重新创建它们。这样做工作:

MATCH (a:Entity {id1:"1"}), (c:Entity {id2:"2"})
WITH a, c
// get rels from node c
MATCH (c)-[r]-(b)
WITH a, c, r, b
// create the same rel from node a
MERGE (b)-["r.rel_type" {prop1:r.prop1, prop2:r.prop2}]->(a)

使用neo4j 3,有所谓的程序,它们是服务器的插件,可以从Cypher查询中调用。 apoc程序包提供了满足您需求的程序:https://neo4j-contrib.github.io/neo4j-apoc-procedures/

首先在服务器上安装apoc插件,然后使用类似:

的内容
// create relationships with dynamic types
CALL apoc.create.relationship(person1,'KNOWS',{key:value,…​}, person2)

// merge nodes
CALL apoc.refactor.mergeNodes([node1,node2])