I'm trying to implement a soft delete in Neo4j. The graph described in Cypher from Alice's viewpoint is as such:
(clyde:User)<-[:FOLLOWS]-(alice:User)-[:LIKES]->(bob:User)
Instead of actually deleting a node and its relationships, I'm
- changing its label so it can no longer be looked up directly, i.e. dropping its
User
label and adding a_User
label (notice the underscore) - replacing its relationships so it can't be reached anymore by my normal queries, e.g. deleting its
:FOLLOWS
relationships and replacing it with:_FOLLOWS
relationships.
So this is basically the equivalent of moving a row to an archiving table in a relational database. I figured this is a pretty efficient approach because you're effectively never visiting the parts of the graph that have been soft-deleted. Also, you don't have to modify any of your existing queries.
The result of soft-deleting Alice should be this:
(clyde:User)<-[:_FOLLOWS]-(alice:_User)-[:_LIKES]->(bob:User)
My first attempt at the query was this:
match (user:User {Id: 1})
optional match (user)-[follows:FOLLOWS]->(subject)
remove user:User set user:_User
delete follows
create (user)-[:_FOLLOWS]->(subject);
The problem is that when this user is not following anyone, the query tries to create a relationship between user
and null
because the second match is optional, so it gives me this error: Other node is null.
My second attempt was this:
match (user:User {Id: 1})
remove user:User set user:_User
optional match (user)-[follows:FOLLOWS]->(subject)
foreach (f in filter(f in collect({r: follows, n: subject}) where f.r is not null) | delete f.r create (user)-[:_FOLLOWS]->(f.n));
So I'm putting the relationship and the subject into a map, collecting these maps in a collection, throwing every "empty" map away and looping over the collection. But this query gives me this error:
SyntaxException: Invalid input '.': expected an identifier character, node labels, a property map, whitespace or ')' (line 1, column 238)
Does anyone know how I can fix this?
Thanks, Jan