cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Cloning subgraphs and keep the cloned nodes connected to other (not cloned) "external" nodes

janezic
Graph Voyager

I'm using apoc.refactor.cloneSubgraphFromPaths to clone a subgraph. The leafs of this subgraph are related to other nodes (which should not be cloned). Anyway, the cloned nodes should inherit this relationship to those not cloned nodes ("external" to the cloned subgraph).

Is there an easy way for that?

THX, JJJ

2 REPLIES 2

Bennu
Graph Fellow

Hi @janezic !

Im pretty sure that on your use case the best way to do so is extending APOC in order to create your own procedure able to do that.

Meanwhile, I offer you one option/idea that is half deprecated but It can be easily adjusted.

Using the base graph:

CREATE  (rootA:Root{name:'A'}),
        (rootB:Root{name:'B'}),
        (n1:Node{name:'node1', id:1}),
        (n2:Node{name:'node2', id:2}),
        (n3:Node{name:'node3', id:3}),
        (n4:Node{name:'node4', id:4}),
        (n5:Node{name:'node5', id:5}),
        (n6:Node{name:'node6', id:6}),
        (n7:Node{name:'node7', id:7}),
        (n8:Node{name:'node8', id:8}),
        (n9:Node{name:'node9', id:9}),
        (n10:Node{name:'node10', id:10}),
        (n11:Node{name:'node11', id:11}),
        (n12:Node{name:'node12', id:12})
        CREATE (rootA)-[:LINK]->(n1)-[:LINK]->(n2)-[:LINK]->(n3)-[:LINK]->(n4)
        CREATE                  (n1)-[:LINK]->(n5)-[:LINK]->(n6)<-[:LINK]-(n7)
        CREATE                                (n5)-[:LINK]->(n8)
        CREATE                                (n5)-[:LINK]->(n9)-[:DIFFERENT_LINK]->(n10)
        CREATE (rootB)-[:LINK]->(n11);

You can clone part of it with (notice I create a specifix rule to do so)

MATCH (rootA:Root {name:'A'})
WITH rootA
MATCH path = (rootA)-[:LINK*]->(node)
where NONE(n in nodes(path) where n.name = 'node6' or n.name = 'node9')
UNWIND relationShips(path) AS r
WITH collect(path) as paths, collect(DISTINCT endNode(r))   AS endNodes, 
     collect(DISTINCT startNode(r)) AS startNodes
UNWIND endNodes AS leaf
WITH paths, leaf WHERE NOT leaf IN startNodes
WITH   collect(leaf) as leafs, paths
CALL apoc.refactor.cloneSubgraphFromPaths(paths, {})
YIELD input, output
WITH input as inp, output as out, leafs
MATCH (n)
where id(n) = inp
and n in leafs
with n, out
CALL apoc.refactor.cloneNodesWithRelationships([n])
yield input, output
CALL apoc.refactor.mergeNodes([out,output],{
  properties:"combine",
  mergeRels:false
})
yield node
return input, output,out,  node 

Lemme know if it's easy to read/useful on your use case.

Bennu

Thank you very much, I will try this next time it Is needed (in the meanwhile I have just cloned the subgraphs and created the relationships by hand) .

THX again and best regards,
JJJ