7vingt
7vingt

Reputation: 301

Neo4 / Cypher : delete all relationships of a nodes

i would like to delete all relationships (incoming and outcoming) of a node (the relationships can go on many differents nodes)

something like :

start n=node:(1000) MATCH n<-[r]->anynode DELETE r

Does not work because here "anynode" is interpreted as the "first" linked node that match.

Any ideas?

Upvotes: 3

Views: 1705

Answers (2)

Andy Gout
Andy Gout

Reputation: 302

I encountered an issue using solution by @eve-freeman when trying to delete all relationships as part of a larger update action (i.e. delete existing relationships and then create new ones, as well as updating a node property):

MATCH (n:Node { uuid: '1' })
OPTIONAL MATCH (n)-[r]-()
DELETE r
WITH n
MATCH (f:Foo { uuid: '2' })
CREATE (n)-[:LIKES]->(f)
WITH n
MATCH (b:Bar { uuid: '3' })
CREATE (n)<-[:LOVES]-(b)
SET n.name = 'Howard'
RETURN n

For some reason it created a duplicate entry (I'd be interested to find out why this happens):

"n"
{"name":"Howard","uuid":"1"}
{"name":"Howard","uuid":"1"}
Set 2 properties, deleted 2 relationships, created 4 relationships, started streaming 2 records after 6 ms and completed after 6 ms.

Using the below (COLLECT and then FOREACH) seems to work:

MATCH (n:Node { uuid: '1' })
OPTIONAL MATCH (n)-[r]-()
WITH n, COLLECT (r) AS rels
FOREACH (r IN rels | DELETE r)
WITH n
MATCH (f:Foo { uuid: '2' })
CREATE (n)-[:LIKES]->(f)
WITH n
MATCH (b:Bar { uuid: '3' })
CREATE (n)<-[:LOVES]-(b)
SET prd.name = 'Howard'
RETURN n

Returns:

"n"
{"name":"Howard","uuid":"1"}
Set 1 property, deleted 2 relationships, created 2 relationships, started streaming 1 record after 3 ms and completed after 3 ms.

Update (14 Aug 2020):

it created a duplicate entry

This is incorrect. It does not actually create a duplicate entry, only duplicate results. However, it does create duplicates of both of the (n)-[:LIKES]->(f) and (n)<-[:LOVES]-(b) relationships.

This is caused by the presence of more than one pre-existing relationship between (n) and other nodes (in the above scenario, (n) had relationships to two other nodes).

Following OPTIONAL MATCH (n)-[r]-(), the query is dealing with two rows: one for each relationship that has been matched (each row also includes the (n) node itself).

DELETE r then deletes the relationship included in each row.

In the WITH n command, n will still represent the two rows of results, even though the relationships have been deleted, so each row now only contains the (n) node (which is the same on each row).

This results in the subsequent commands being run for each row, and consequently the duplicate relationships being created and the duplicate results.

The solution is to ensure that after the deletion of the rows that only distinct rows are carried over, which is achieved by using WITH DISTINCT n, e.g.

MATCH (n:Node { uuid: '1' })
OPTIONAL MATCH (n)-[r]-()
DELETE r
WITH DISTINCT n
MATCH (f:Foo { uuid: '2' })
CREATE (n)-[:LIKES]->(f)
WITH n
MATCH (b:Bar { uuid: '3' })
CREATE (n)<-[:LOVES]-(b)
SET n.name = 'Howard'
RETURN n

Both this and the above COLLECT/FOREACH approach will achieve the same effect.

Upvotes: 0

Eve Freeman
Eve Freeman

Reputation: 33155

You want:

start n=node(1000) 
match n-[r]-() 
delete r;

Upvotes: 13

Related Questions