首页 > 解决方案 > 如何在 neo4j 中复制节点树?

问题描述

如何从现有节点树创建完整节点树,实际上我有 1 个节点,我需要找到所有具有我现有顶部节点的关系和节点。我需要为另一个节点创建完整的节点树。

使用关系从 A 复制所有节点树并为 B 节点创建重复的相同节点和关系

在此处输入图像描述

标签: neo4jneo4j-apoc

解决方案


好吧,这是一个棘手的问题。

正如其他人提到的那样apoc.refactor.cloneNodesWithRelationships()可以提供帮助,但这也会导致克隆节点和原始节点之间的关系,而不仅仅是克隆,因为这个过程没有考虑到这种用例。

所以这需要我们做一些 Cypher 杂技来从克隆节点中找到不去克隆节点的关系,以便我们可以删除它们。

但是同时我们还必须识别旧的根节点,以便我们可以重构与新根的关系(这需要对传入和传出关系进行单独处理)。

这是一个可以解决问题的查询,因为您没有提供有关图表的任何详细信息,所以对节点进行假设:

MATCH (a:Root{name:'A'})
WITH a, id(a) as aId
CALL apoc.path.subgraphNodes(a, {}) YIELD node
WITH aId, collect(node) as nodes
CALL apoc.refactor.cloneNodesWithRelationships(nodes) YIELD input, output
WITH aId, collect({input:input, output:output}) as createdData, collect(output) as createdNodes
WITH createdNodes, [item in createdData WHERE item.input = aId | item.output][0] as aClone // clone of root A node
UNWIND createdNodes as created
OPTIONAL MATCH (created)-[r]-(other)
WHERE NOT other in createdNodes
DELETE r // get rid of relationships that aren't between cloned nodes
// now to refactor relationships from aClone to the new B root node
WITH DISTINCT aClone
MATCH (b:Root{name:'B'})
WITH aClone, b
MATCH (aClone)-[r]->()
CALL apoc.refactor.from(r, b) YIELD output
WITH DISTINCT b, aClone
MATCH (aClone)<-[r]-()
CALL apoc.refactor.to(r, b) YIELD output
WITH DISTINCT aClone
DETACH DELETE aClone

推荐阅读