user3714269
user3714269

Reputation: 129

How to duplicate node tree in neo4j?

How can I create full node tree from existing node tree, Actually i have 1 node and i need to find all relation and nodes that has my existing top node. I need to create full node tree to another node.

Copy All Node Tree from A with Relation and create Duplicate same node and relation for B Node

enter image description here

Upvotes: 2

Views: 559

Answers (1)

InverseFalcon
InverseFalcon

Reputation: 30397

Okay, this is a tricky one.

As others have mentioned apoc.refactor.cloneNodesWithRelationships() can help, but this will also result in relationships between cloned nodes and the originals, not just the clones, as this proc wasn't written with this kind of use case in mind.

So this requires us to do some Cypher acrobatics to find the relationships from the cloned nodes that don't go to the cloned nodes so we can delete them.

However at the same time we also have to identify the old root node so we can refactor relationships to the new root (this requires separate processing for incoming and outgoing relationships).

Here's a query that should do the trick, making assumptions about the nodes since you didn't provide any details about your graph:

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

Upvotes: 3

Related Questions