Reputation: 10868
Given a linked list pattern like this:
(list) -[:next]-> (a) -[:next]-> (b) -[next...]-> (z)
i.e. Where every element in the list is guaranteed to have an incoming (preceding) next
relationship, but the last one in the list will have no outgoing (following) one...
I have this query for atomically removing one or more nodes from such lists:
START nodeToRemove = node({ids})
MATCH nodeBefore -[relBefore:next]-> nodeToRemove
DELETE relBefore
WITH nodeToRemove, nodeBefore
MATCH nodeToRemove -[relAfter:next]-> nodeAfter
CREATE nodeBefore -[relNew:next]-> nodeAfter
SET relNew = relAfter
WITH relAfter
DELETE relAfter
This is a pre-2.0 style query, but the syntax works with Neo4j 2.0 too. It says, for each input node:
Delete the incoming (i.e. preceding) next
relationship.
Then look for an outgoing (i.e. following) next
relationship.
If there is one, "rewire" it to connect the (before)
node to the (after)
one.
(Since relationship connections are immutable in Neo4j, this last step is achieved by creating a new relationship with the same props as the old one, then deleting the old one.)
(And this query is written in this way specifically because the last node in the list won't have an outgoing next
relationship, but always has an incoming one.)
This used to work fine with Neo4j 1.8, but it fails now in Neo4j 1.9 if I pass in adjacent nodes. The error is this:
Error: java.lang.IllegalStateException: Relationship <id> has been deleted
Which implies that the entire query isn't "processed" before relationships get deleted. This used to work in Neo4j 1.8 though, I swear. =)
How can I fix this? Here's a live console to play with this for yourself:
http://console.neo4j.org/r/jhk8cc
Paste in the query above, and just replace {ids}
with 1, 2
. Individual nodes like 1
and 2
work. (Thanks @cybersam for the initial tip!)
Upvotes: 3
Views: 282
Reputation: 66989
It seems that, as of 1.9, the SET operation is is being performed after the 'DELETE relAfter' operation.
How about splitting things up a bit more:
START nodeToRemove = node({id})
MATCH nodeBefore -[relBefore:next]-> nodeToRemove
DELETE relBefore
WITH nodeToRemove, nodeBefore
MATCH nodeToRemove -[relAfter:next]-> nodeAfter
CREATE nodeBefore -[relNew:next]-> nodeAfter
SET relNew = relAfter
WITH relAfter
DELETE relAfter
Upvotes: 3