Reputation: 23
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
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 Node
s, 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
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