Reputation: 678
When I run this query:
START n1=node(7727), n2=node(7730)
MATCH n1-[r:SKILL]->n2 RETURN r
it gives me a list of duplicate relationships that I have between the two nodes. what do I add to the cypher query to iterate over the relationship to keep one relationship and delete the rest?
Upvotes: 27
Views: 17469
Reputation: 31
you can use mergeRelationships:
MATCH (n1)-[r:SKILL]->(n2) RETURN r
WITH n1, n2, COLLECT(r) AS rels
WHERE SIZE(rels) > 1
CALL apoc.refactor.mergeRelationships(rels, {properties:"discard"})
YIELD rel RETURN rel
about the operation types:
from official docs: https://neo4j.com/labs/apoc/4.1/overview/apoc.refactor/apoc.refactor.mergeRelationships/
Upvotes: 0
Reputation: 801
Here's a great way to find all your duplicate relationships and get some visibility into where they are happening.
MATCH p=(n)-[r1]->(g)<-[r2]-(n)
WHERE type(r1) = type(r2) AND r1 <> r2
RETURN type(r1) as relType, labels(n), labels(g), count(p)
Upvotes: 0
Reputation: 8495
If you have trust issues about random queries that deletes data from the DB you can do what I did.
First you might want to check if the selected relationships are really duplicates. This query will set a property willBeDeleted to true, so you can check if you really want to delete those.
match (a)-[r]->(b)
with a,b,type(r) as typ, tail(collect(r)) as coll
foreach(x in coll | set x.willBeDeleted=true)
Now you can check which relationships will be deleted actually.
match(a)-[r]-(b)
where r.willBeDeleted=true
return a, b, r
If you think the right relationships will be deleted, then you can execute this query to delete the duplicates.
match (a)-[r]->(b)
with a,b,type(r) as typ, tail(collect(r)) as coll
foreach(x in coll | delete x)
Upvotes: 5
Reputation: 81
With Neo4J 4.x and to globally remove duplicate relationships, you'll want to use the following instead. The syntax has changed slightly and the start
prefix mentioned in the other reply no longer works.
match ()-[r]->()
match (s)-[r]->(e)
with s,e,type(r) as typ, tail(collect(r)) as coll
foreach(x in coll | delete x)
Upvotes: 8
Reputation: 39925
To do this for two known nodes:
start n=node(1), m=node(2) match (n)-[r]->(m)
with n,m,type(r) as t, tail(collect(r)) as coll
foreach(x in coll | delete x)
To do this globally for all relationships (be warned this operation might be very expensive depending on the size of your graph):
start r=relationship(*)
match (s)-[r]->(e)
with s,e,type(r) as typ, tail(collect(r)) as coll
foreach(x in coll | delete x)
Upvotes: 42