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.

Merge existing relationships of same type combining properties

Hi all,

I've been struggling for days with the following situation.

I have a series of pairwise relationships of same type involving the same nodes, some of them with different values for some properties and with different directions.

To make things clear:

What I have:
Rel 1 (n1)-[:CO_STARS_WITH in{'Movie A'}]->(n2)
Rel 2 (n1)<-[:CO_STARS_WITH in{'Movie B'}]-(n2)

The different directions were defined arbitrarily by merging the relations in an undirected manner: (n1)-[:CO_STARS_WITH]-(n2)

What I need:

Merge Rel 1 and Rel 2 into one relation, combining their properties in a list and the count of the merged relations also as a property.

I've been trying with apoc.refactor.mergeRelationships:

Match (n1)-[rel:CO_STARS_WITH]-(n2) 
With collect(rel) as rels
CALL apoc.refactor.mergeRelationships(rels,{properties:"combine"}) YIELD rel
RETURN rel

but I always get the following error:

Failed to invoke procedure apoc.refactor.mergeRelationships: Caused by: java.lang.RuntimeException: All Relationships must have the same start and end nodes.

How to overcome this limitation of apoc.refactor.mergeRelationships ?

Is it possible to "normalize" relationships direction?

I've tried almost everything.

Any help would be appreciated.

1 ACCEPTED SOLUTION

If this represents your starting data:

MERGE (:Actor{id:1})-[:CO_STARS_WITH{in:"Movie A"}]->(:Actor{id:2})
MERGE (:Actor{id:1})<-[:CO_STARS_WITH{in:"Movie B"}]-(:Actor{id:2})

does this give you the output you want?

MATCH (n1:Actor{id:1})-[r:CO_STARS_WITH]-(n2:Actor{id:2})
WITH n1, n2, collect(r) AS rels
MERGE (n1)-[rb:BETTER_CO_STARS_WITH]->(n2)
SET rb.in = apoc.coll.union([head(rels).in], [last(rels).in]), rb.size = size(rels)
WITH n1,rb,n2,rels
UNWIND rels AS r // only include this and the next line if you want to remove the existing relationships
DELETE r
RETURN n1,rb,n2

View solution in original post

2 REPLIES 2

If this represents your starting data:

MERGE (:Actor{id:1})-[:CO_STARS_WITH{in:"Movie A"}]->(:Actor{id:2})
MERGE (:Actor{id:1})<-[:CO_STARS_WITH{in:"Movie B"}]-(:Actor{id:2})

does this give you the output you want?

MATCH (n1:Actor{id:1})-[r:CO_STARS_WITH]-(n2:Actor{id:2})
WITH n1, n2, collect(r) AS rels
MERGE (n1)-[rb:BETTER_CO_STARS_WITH]->(n2)
SET rb.in = apoc.coll.union([head(rels).in], [last(rels).in]), rb.size = size(rels)
WITH n1,rb,n2,rels
UNWIND rels AS r // only include this and the next line if you want to remove the existing relationships
DELETE r
RETURN n1,rb,n2

Thanks @terryfranklin82. I ended up circumventing the problem in another way, but your tip also works.