Remove leaf nodes with a single relationship in NEO4J

I am trying to delete leaf nodes in Neo4j, but only those nodes with a single incoming relationship. (I am very close.)

I have one The query returns the exact node I want to delete. However, when I replace RETURN with DELETE, it deletes more than what the query returns. This is the complete sequence:

neo4j- sh (?)$match (n)-[r]->(p) return n, r, p ;
+-------------------- ----------------------------------------+
| n | r | p |
+------------------------------------------- -----------------+
| Node[2164]{name:"a"} | :has[2616]{} | Node[2165]{name: "b"} |
| Node[2164]{name:"a"} | :has[2617]{} | Node[2166]{name:"c"} |
| Node[2166 ]{name:"c"} | :has[2619]{} | Node[2168]{name:"e"} |
| Node[2167]{name:"d"} | :has[2618 ]{} | Node[2165]{name:"b"} |
+----------------------------- -------------------------------+

This query is perfect:

neo4j-sh (?)$match ()-[r:has]->(n)
> with n,count(r) as rel_cnt
> where rel_cnt = 1 and NOT (n)-->()
> return n.name, rel_cnt;
+------------------+
| n.name | rel_cnt |
+------------------+
| "e" | 1 |
+-------------- ----+

But the deletion deletes 2 nodes and 3 relations?

neo4j-sh (?)$match ()-[r:has]->(n)
> with n, r, count(r) as rel_cnt
> where rel_cnt = 1 and NOT (n)-->()
> delete n, r;
+--------------- ----+
| No data returned. |
+-------------------+
Nodes deleted: 2
Relationships deleted: 3

This is all that is left

neo4j-sh (?)$match (n)-[r]-> (p) return n, r, p ;
+----------------------------------- -------------------------+
| n | r | p |
+-------- -------------------------------------------------- --+
| Node[2164]{name:"a"} | :has[2617]{} | Node[2166]{name:"c"} |
+----- -------------------------------------------------- -----+
neo4j-sh (?)$match (n) return n;
+--------------------- -+
| n |
+----------------------+
| Node[2169]{name:" a"} |
| Node[2171]{name:"c"} |
| Node[2172]{name:"d"} |
+------- ---------------+

Why delete node’b’? It is not displayed in the query results.

Even in addition to RETURN / DELETE, the query actually Not the same. The return query carries n,count(r) to the second query part, and the delete query carries n,r,count(r). Try to return the delete query to view it, i.e. run it

neo4j-sh (?)$match ()-[r:has]->(n)
> with n, r, count(r) as rel_cnt
> where rel_cnt = 1 and NOT (n)-->()
//> delete n, r;
> return *;

You will get something like this

+-------------------------------------- ---------+
| n | r | rel_cnt |
+------------------------ -----------------------+
| Node[2165]{name:"b"} | :has[2616]{} | 1 |
| Node[2165]{name:"b"} | :has[2618]{} | 1 |
| Node[2168]{name:"e"} | :has[2619] {} | 1 |
+---------------------------------------- -------+

The reason for the different results is that the pipe n, count(r) means something like “count r per n”, and there is only one case where “count r per n = 1”. But another pipeline means “calculate the number of every n and every r”, if you calculate or group by yourself, then it will become one every time. The reason for not deleting some content is that it has never been matched or otherwise Filter criteria (NOT(n) ->()) exclude, so rel_cnt = 1 is invalid.

If you want to calculate the relationships first and then delete them conditionally, you can collect them, Filter the collection size and then delete it from the collection. Try something similar

MATCH ()-[r:has]->(n)
WITH n, collect (r) as rr
WHERE length(rr) = 1 AND NOT n-->()
FOREACH (r IN rr | DELETE r)
DELETE n

I tried to delete leaf nodes in Neo4j, but only those nodes with a single incoming relationship. (I am very close.)

I have a query that returns me The exact node I want to delete. However, when I replace RETURN with DELETE, it deletes more than what the query returns. This is the complete sequence:

neo4j-sh (? )$match (n)-[r]->(p) return n, r, p ;
+----------------------- -------------------------------------+
| n | r | p |< br />+---------------------------------------------- --------------+
| Node[2164]{name:"a"} | :has[2616]{} | Node[2165]{name:"b" } |
| Node[2164]{name:"a"} | :has[2617]{} | Node[2166]{name:"c"} |
| Node[2166]{name :"c"} | :has[2619]{} | Node[2168]{name:"e"} |
| Node[2167]{name:"d"} | :has[2618]{} | Node[2165]{name:"b"} |
+-------------------------------- ----------------------------+

This query is perfect:

neo4j-sh (?)$match ()-[r:has]->(n)> with n,count(r) as rel_cnt
> where rel_cnt = 1 and NOT (n)-->()
> return n.name, rel_cnt;
+- -----------------+
| n.name | rel_cnt |
+---------------- --+
| "e" | 1 |
+------------------+

But delete it 2 nodes and 3 relationships?

neo4j-sh (?)$match ()-[r:has]->(n)
> with n, r, count(r) as rel_cnt
> where rel_cnt = 1 and NOT (n)-->()
> delete n, r;
+--------------- ----+
| No data returned. |
+-------------------+
Nodes deleted: 2
Relationships deleted: 3

This is all that is left

neo4j-sh (?)$match (n)-[r]-> (p) return n, r, p ;
+----------------------------------- -------------------------+
| n | r | p |
+-------- -------------------------------------------------- --+
| Node[2164]{name:"a"} | :has[2617]{} | Node[2166]{name:"c"} |
+----- -------------------------------------------------- -----+
neo4j-sh (?)$match (n) return n;
+--------------------- -+
| n |
+----------------------+
| Node[2169]{name:" a"} |
| Node[2171]{name:"c"} |
| Node[2172]{name:"d"} |
+------- ---------------+

Why delete node’b’? It is not displayed in the query results.

Even in addition to RETURN / DELETE, the query is actually different. The returned query carries n, count(r) Go to the second query part, the delete query carries n, r, count(r). Try to return the delete query to view it, that is, run it

neo4j-sh ( ?)$match ()-[r:has]->(n)
> with n, r, count(r) as rel_cnt
> where rel_cnt = 1 and NOT (n)--> ()
//> delete n, r;
> return *;

You will get something like this

+ -----------------------------------------------+
| n | r | rel_cnt |
+------------------------------------ -----------+
| Node[2165]{name:"b"} | :has[2616]{} | 1 |
| Node[2165]{name :"b"} | :has[2618]{} | 1 |
| Node[2168]{name:"e"} | :has[2619]{} | 1 |
+-- ---------------------------------------------+

The reason for the different results is that pipe n, count(r) means something like “count r per n”, and only one case is “count r per n = 1”. But another pipe means “calculate every n and the number of each r”, if you calculate or group by yourself, then it will become one each time. The reason for not deleting some content is that it has never been matched or been matched by other filter criteria (NOT(n) ->() ) Excluded, so rel_cnt = 1 is invalid.

If you want to calculate the relationships first and then delete them conditionally, you can collect them, filter the collection size, and then delete from the collection. Try something similar

MATCH ()-[r:has]- >(n)
WITH n, collect(r) as rr
WHERE length(rr) = 1 AND NOT n-->()
FOREACH (r IN rr | DELETE r)< br />DELETE n

Leave a Comment

Your email address will not be published.