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.

Creating relationship before cloning nodes

mkretsch
Node Clone

I have a great query, which let's me clone nodes, and then merge them, which maintains the original node in case I merged incorrectly. I would love an edge
(a1) --[MERGED]->(node)
(a2)--[MERGED]->(node)
To essentially connect the originals with the newly merged clones. How might I do that in this query?

MATCH (a1), (a2)
WHERE id(a1) = {{"Source":node}} AND id(a2) = {{"Target":node}}
SET a1:Merged, a2:Merged
SET a1.uuidoriginal = a1.uuid
SET a2.uuidoriginal = a2.uuid
WITH head(collect([a1,a2])) as nodes
CALL apoc.refactor.cloneNodes(nodes, true, ["uuid"])
YIELD input, output
SET output.uuid = apoc.create.uuid()
WITH collect(output) as nodes
CALL apoc.refactor.mergeNodes(nodes,{
properties: "combine",
mergeRels:true
})
YIELD node
SET node.name = apoc.text.join(node.name,",")
REMOVE node:Merged
RETURN node

1 ACCEPTED SOLUTION

Try this:

MATCH (a1), (a2)
WHERE a1.id =1 AND a2.id = 2
SET a1:Merged, a2:Merged
SET a1.uuidoriginal = a1.uuid
SET a2.uuidoriginal = a2.uuid
WITH a1, a2
CALL apoc.refactor.cloneNodes([a1,a2], true, ["uuid"])
YIELD output
SET output.uuid = apoc.create.uuid()
WITH collect(output) as nodes, a1, a2
CALL apoc.refactor.mergeNodes(nodes,{
properties: "combine",
mergeRels:true
})
YIELD node
SET node.name = apoc.text.join(node.name,",")
REMOVE node:Merged
MERGE (a1)-[:MERGED]->(node)
MERGE (a2)-[:MERGED]->(node)
RETURN node

BTW- I changed the initial 'WHERE' clause so I could test it - revert back.

View solution in original post

6 REPLIES 6

Try this:

MATCH (a1), (a2)
WHERE a1.id =1 AND a2.id = 2
SET a1:Merged, a2:Merged
SET a1.uuidoriginal = a1.uuid
SET a2.uuidoriginal = a2.uuid
WITH a1, a2
CALL apoc.refactor.cloneNodes([a1,a2], true, ["uuid"])
YIELD output
SET output.uuid = apoc.create.uuid()
WITH collect(output) as nodes, a1, a2
CALL apoc.refactor.mergeNodes(nodes,{
properties: "combine",
mergeRels:true
})
YIELD node
SET node.name = apoc.text.join(node.name,",")
REMOVE node:Merged
MERGE (a1)-[:MERGED]->(node)
MERGE (a2)-[:MERGED]->(node)
RETURN node

BTW- I changed the initial 'WHERE' clause so I could test it - revert back.

mkretsch
Node Clone

@glilienfield

This query is working same as before and not producing the edges. Any further ideas?

I've tried the following that have also not worked (moving the edge creation earlier and adding a with clause to what you suggested)

MATCH (a1), (a2)
WHERE id(a1) = {{"Source":node}} AND id(a2) = {{"Target":node}}
SET a1:Merged, a2:Merged
SET a1.uuidoriginal = a1.uuid
SET a2.uuidoriginal = a2.uuid
WITH a1, a2
CALL apoc.refactor.cloneNodes([a1,a2], true, ["uuid"])
YIELD output
WITH output, a1, a2
SET output.uuid = apoc.create.uuid()
MERGE (a1)-[:MERGED]->(output)
MERGE (a2)-[:MERGED]->(output)
WITH collect(output) as nodes
CALL apoc.refactor.mergeNodes(nodes,{
properties: "combine",
mergeRels:true
})
YIELD node
SET node.name = apoc.text.join(node.name,",")
REMOVE node:Merged
RETURN node


MATCH (a1), (a2)
WHERE id(a1) = {{"Source":node}} AND id(a2) = {{"Target":node}}
SET a1:Merged, a2:Merged
SET a1.uuidoriginal = a1.uuid
SET a2.uuidoriginal = a2.uuid
WITH a1, a2
CALL apoc.refactor.cloneNodes([a1,a2], true, ["uuid"])
YIELD output
SET output.uuid = apoc.create.uuid()
WITH collect(output) as nodes, a1, a2
CALL apoc.refactor.mergeNodes(nodes,{
properties: "combine",
mergeRels:true
})
YIELD node
WITH node, a1, a2
SET node.name = apoc.text.join(node.name,",")
REMOVE node:Merged
MERGE (a1)-[:MERGED]->(node)
MERGE (a2)-[:MERGED]->(node)
RETURN node

I will look later. It worked for me when I tested it. Can you include your test data.

I'm working with extremely simple test data right now
(a1:Person {name: Test 8, uuid: ec6b63e1-e82d-4ef5-8c3c-34639e34d027})
(a2:Person {name: Test 9, uuid: 1150197b-47df-4725-b30a-1a61f4f69037})
(b: Entity {name: Company, uuid: bd0b9480-186a-42e9-92b8-7a253b619453})
(a1)-[DIRECTOR]->(b)
(a2)-[SHAREHOLDER]->(b)

My current results
(a1:Person:Merged {name: Test 8, uuid: ec6b63e1-e82d-4ef5-8c3c-34639e34d027, uuidoriginal: ec6b63e1-e82d-4ef5-8c3c-34639e34d027})
(a2:Person:Merged {name: Test 9, uuid: 1150197b-47df-4725-b30a-1a61f4f69037, uuidoriginal: 1150197b-47df-4725-b30a-1a61f4f69037})
(a1)-[DIRECTOR]->(b)
(a2)-[SHAREHOLDER]->(b)
(c)-[DIRECTOR]->(b)
(c)-[SHAREHOLDER]->(b)
(c:Person {name: Test 8, Test 9, uuid: [ 8fe2428e-c53a-4bc4-b0aa-b7069db95bd9, feb8ae7a-2918-4242-be61-d299abfbed68], uuidoriginal: [ec6b63e1-e82d-4ef5-8c3c-34639e34d027, 1150197b-47df-4725-b30a-1a61f4f69037]})

What I am missing
(a1)-[MEGRED]->(c)
(a2)-[MERGED]->(c)

I used the following test data:

merge(a1:Person {name: 'Test 8', uuid: 'ec6b63e1-e82d-4ef5-8c3c-34639e34d027'})
merge(a2:Person {name: 'Test 9', uuid: '1150197b-47df-4725-b30a-1a61f4f69037'})
merge(b: Entity {name: 'Company', uuid: 'bd0b9480-186a-42e9-92b8-7a253b619453'})
merge(a1)-[:DIRECTOR]->(b)
merge(a2)-[:SHAREHOLDER]->(b)

With the following script:

MATCH (a1), (a2)
WHERE a1.name = 'Test 8' AND a2.name = 'Test 9'
SET a1:Merged, a2:Merged
SET a1.uuidoriginal = a1.uuid
SET a2.uuidoriginal = a2.uuid
WITH a1, a2
CALL apoc.refactor.cloneNodes([a1,a2], true, ["uuid"])
YIELD output
SET output.uuid = apoc.create.uuid()
WITH collect(output) as nodes, a1, a2
CALL apoc.refactor.mergeNodes(nodes,{
properties: "combine",
mergeRels:true
})
YIELD node
SET node.name = apoc.text.join(node.name,",")
REMOVE node:Merged
MERGE (a1)-[:MERGED]->(node)
MERGE (a2)-[:MERGED]->(node)
RETURN node

I got the following result:

I believe this is what you want. Can you try the above two scripts in your environment?

This sounds very silly, it was working the whole time. I was working in visualization software and had not turned the edge MERGED on in the schema! Thank you for your extra effort and the solution, really appreciate it! Your query worked.