Cétautomatix
Cétautomatix

Reputation: 23

Neo4j - Howto delete duplicate relations based on their properties

I have nodes between which there exist multiple relations. Each relation has two properties p1 and p2. A relation is duplicate only when it has the same value for properties p1 and p2.

MATCH (a:Node)-[r1:Rel]->(b:Node)
MATCH (a:Node)-[r2:Rel]->(b:Node)
WHERE ((r1.p1 = r2.p1) AND (r1.p2 = r2.p2))
WITH a,b, TAIL(collect(r1)) AS coll
FOREACH (x in coll| DELETE x)

This does not produce the expected result. The code above removes all, except the first relation. Tail removes all except the first, which it seems to do. It does not take into account the properties however. How can i delete duplicate relations and take into account their properties ?

Upvotes: 2

Views: 203

Answers (2)

cybersam
cybersam

Reputation: 67044

This should work:

MATCH (a:Node)-[r:Rel]->(b:Node)
WITH a, b, r.p1 AS p1, r.p2 AS p2, COLLECT(r)[1..] AS unwanted
FOREACH(x IN unwanted | DELETE x)

For each pair of Nodes, it uses aggregation to collect all the relationships in the same direction having the same p1 and p2 values, and then deletes all but one.

The [1..] list operation does essentially the same thing as the TAIL function.

Upvotes: 1

terryf82
terryf82

Reputation: 91

The matching logic looks right, I think your collect & tail code is where the problem lies. This works on a simple test graph I created:

MATCH (a:Node)-[r1:REL]->(b:Node), (a:Node)-[r2:REL]->(b:Node)
WHERE (r1.p1 = r2.p1 AND r1.p2 = r2.p2)
WITH collect(r2) AS rels
WHERE size(rels) > 1
UNWIND tail(rels) AS dupe
DELETE dupe

You could also make the matching more flexible by using the properties function:

WHERE properties(r1) = properties(r2)

Upvotes: 1

Related Questions