Reputation: 77
I've created some nodes that describe a process. Using pretty standard best practices it looks something like this:
(process:Process)-[:FIRST_STEP {parent:id(process)}]->(step1:Step)-[:NEXT {parent:id(process)}]->etc.
So it's a parent node of the Process type followed by a bunch of steps each of the step type, and each relationship proceeding from the parent has a property of parent with the id of the parent process.
This is done so that a step could be included in multiple processes, and works pretty well.
Now I need to delete a process and all of its steps. What I want to avoid is deleting any child step of the parent that belongs in another process's string of steps.
My first step is:
match(p:Process)-[rel:FIRST_STEP | :NEXT* {parent:id(p)}]->(step)
where id(p) = 1234
return p, step
This will return the Process and all the steps. Now I want to not return any steps that are spoken for by other Processes. This is what I have, but it's not working and I could use any ideas:
match(p:Process)-[rel:FIRST_STEP | :NEXT* {parent:id(p)}]->(step)
where id(p) = 1234
and not exists(
(step)<-[otherrelation:FIRST_STEP|NEXT]-() WHERE otherrelation.parent <> id(p)
)
The WHERE clause in the exists() section blows it up and I'm not finding documentation on how to do this.
Help much appreciated.
Upvotes: 0
Views: 258
Reputation: 30417
The problem is that patterns in EXISTS()
and NOT EXISTS()
can't be used to introduce new variables, like your otherRelation
.
In the absence of an EXCLUDE MATCH
clause, we have to get by with an OPTIONAL MATCH
on the pattern we don't want, then prune matches where the matched pattern exists.
MATCH(p:Process)-[rel:FIRST_STEP | :NEXT* {parent:id(p)}]->(step)
WHERE id(p) = 1234
WITH p, rel, step
OPTIONAL MATCH (step)<-[otherrelation:FIRST_STEP|NEXT]-()
WHERE otherrelation.parent <> id(p)
WITH p, rel, step
WHERE otherrelation IS NULL
...
Upvotes: 2