Reputation: 3934
I want to find a path (in this case the entire database), where there is a :B
node that has no incoming :s
-edge and then remove all the :B
s of the path.
This is my test database:
MERGE (B1:B {name:"B1"})-[:t]->(B2:B {name:"B2"})-[:t]->(B3:B {name:"B3"})-[:t]->(B4:B {name:"B4"})-[:t]->(B5:B {name:"B5"})-[:t]->(C1:D {name:"D1"})
MERGE (A1:A {name:"A1"})-[:s]->(B1)
MERGE (A2:A {name:"A2"})-[:s]->(B2)
MERGE (A3:A {name:"A3"})-[:s]->(B4)
MERGE (A5:A {name:"A5"})-[:s]->(B5)
5)
The query I tried last is this, but it throws an error:
MATCH p=(n:A)-[*] ->(o:B)-[:t*]->(m:D)
WITH NODES(p)[1..-1] AS Pspace_nodes, o, p
MATCH o WHERE NOT ()-[:s]->(o)
FOREACH (n IN Pspace_nodes| MATCH n-[*]-() DELETE n , r)
Error message:
py2neo.cypher.error.statement.InvalidSyntax: Invalid use of MATCH inside FOREACH (line 4, column 29 (offset: 143))
"FOREACH (n IN Pspace_nodes| MATCH n-[*]-() DELETE n , r)
How do I express this in a valid fashion?
Upvotes: 0
Views: 998
Reputation: 66989
[EDITED]
This might work for you:
MATCH p=(:A)-[r*]-(:D)
WHERE ANY (x IN NODES(p)[1..-1] WHERE x:B AND NOT ()-[:s]->(x))
WITH REDUCE(s =[], y IN NODES(p)[1..-1]| CASE WHEN y:B THEN s + y ELSE s END ) AS todo
UNWIND todo AS node
WITH DISTINCT node
DETACH DELETE node;
In a larger DB, this can take a long time to run because the MATCH
specifies a variable-length path. If this is a problem, you should use a reasonable upper bound (e.g., [r*..5]
).
The WHERE
clause filters for paths with a B
node with no incoming :s
relationship. The REDUCE
function collects all the B
nodes in the path. The UNWIND
puts each B
node in a separate row. The DISTINCT
removes all duplicate nodes so that the deletion attempt will not try to delete a node twice (which causes neo4j to generate an error). The DETACH DELETE
clause will not only delete those B
nodes but also all their relationships (since you are not allowed to delete a node without also doing that).
Upvotes: 1