mota
mota

Reputation: 5475

How to move the properties and relationships of one node to another?

I have two separate nodes in the graph, and at one point I will get a signal that those two nodes should actually be one. So I have to merge the two including their properties (there's no overlap) AND I should maintain the relationships as well.

Example graph: (d)->(a {id:1}), (b)->(c {name:"Sam"})

Desired result: (d)->(a {id:1, name:"Sam"}), (b)->(a {id:1, name:"Sam"})

The label a doesn't have to be the case really in the result - the point is we will have only one node representing the original two.

The following merges the properties fine.

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

But I can't seem to find a way to move/copy the relationships.

The specs:

Any thoughts?

Update:

The following works, assuming the type and properties coming to node c are known in advance. Can I improve this to make it more dynamic?

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

Update 2: The above throws unable to load relationship with id error sometimes and I'm not sure why, but it seems it's related to reading/writing at the same time.

Update 3: This is a work around for the error:

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

Upvotes: 2

Views: 2111

Answers (1)

Martin Preusse
Martin Preusse

Reputation: 9369

The problem when moving relationships between nodes is that you can't set the relationship type dynamically.

So you can't MATCH all relationships from node c and recreate them on node a. This does not work:

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)

With neo4j 3 there are so called procedures which are plugins for the server and can be called from Cypher queries. The apoc procedure package provides procedures that do what you need: https://neo4j-contrib.github.io/neo4j-apoc-procedures/

First install the apoc plugin on your server, then use something like:

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

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

Upvotes: 1

Related Questions