I have a linked list of replies off of a Post that looks like this:
With the "first" reply in the list having a NEWEST_REPLY relationship to Post and subsequent replies having a NEXT_REPLY relationship. The query to get the above graph:
MATCH (p:Post {id: $postId})-[:NEWEST_REPLY|NEXT_REPLY*]->(r:Reply)
return p, r
I want to create a cypher query that either
- Creates a reply and creates the NEWEST_REPLY relationship when there are no replies OR
- Creates a reply, deletes the current NEWEST_REPLY relationship, creates a NEXT_REPLY relationship to the previous NEWEST_REPLY and a NEWEST_REPLY relationship to the new Reply.
This statement:
MATCH (p:Post {id: $postId})-[rel:NEWEST_REPLY]->(previousNewestReply:Reply)
DELETE rel
CREATE (r:Reply { id: apoc.create.uuid(), body: $body, createdAt: datetime(), updatedAt: datetime() })
WITH r, p, previousNewestReply
MATCH (u:User)
WHERE u.id = $userId
CREATE (r)<-[:WROTE]-(u)
CREATE (r)<-[:NEWEST_REPLY]-(p)
CREATE (r)-[:NEXT_REPLY]->(previousNewestReply)
RETURN u, p
achieves number 2.
What I now need to do is conditionally run this statement if the rel
in MATCH (p:Post {id: $postId})-[rel:NEWEST_REPLY]->(previousNewestReply:Reply)
exists, but if it does not exist, just create NEWEST_REPLY for the first time as well as creating the reply and the User-[:WROTE]->Reply
relationship. I'm new to cypher and digging into MERGE, CASE, predicate functions and apoc.when() and not sure which would be the simplest and most appropriate.
Here's an attempt at using CASE:
MATCH (p:Post {id: "db7ee38c-fe60-430e-a7c7-0b2514401343"})
RETURN
CASE EXISTS( (p)-[rel:NEWEST_REPLY]->(replies:Reply) )
WHEN true THEN DELETE rel CREATE (r:Reply { id: apoc.create.uuid(), body: "new with CASE1", createdAt: datetime(), updatedAt: datetime() }) WITH r, p, replies MATCH (u:User) WHERE u.id = "e14d409e-d970-4c5c-9cc7-3b224c774835" CREATE (r)<-[:WROTE]-(u) CREATE (r)<-[:NEWEST_REPLY]-(p) CREATE (r)-[:NEXT_REPLY]->(replies)
WHEN false THEN CREATE (r:Reply { id: apoc.create.uuid(), body: "new with CASE2", createdAt: datetime(), updatedAt: datetime() }) WITH r, p, previousNewestReply MATCH (u:User) WHERE u.id = "e14d409e-d970-4c5c-9cc7-3b224c774835" CREATE (r)<-[:WROTE]-(u) CREATE (r)<-[:NEWEST_REPLY]-(p) END
AS result;
And running into the following SyntaxError:
Invalid input 'r': expected whitespace, comment, '{', node labels, MapLiteral, a parameter, a parameter (old syntax), a relationship pattern, '(', '.', '[', '^', '*', '/', '%', '+', '-', "=~", IN, STARTS, ENDS, CONTAINS, IS, '=', '~', "<>", "!=", '<', '>', "<=", ">=", AND, XOR, OR, WHEN, ELSE or END (line 4, column 24 (offset: 145))
"WHEN true THEN DELETE rel CREATE (r:Reply { id: apoc.create.uuid(), body: "new with CASE1", createdAt: datetime(), updatedAt: datetime() }) WITH r, p, replies MATCH (u:User) WHERE u.id = "e14d409e-d970-4c5c-9cc7-3b224c774835" CREATE (r)<-[:WROTE]-(u) CREATE (r)<-[:NEWEST_REPLY]-(p) CREATE (r)-[:NEXT_REPLY]->(replies)"
My sense is that the logic I am attempting in either THEN statements is too complex for a CASE. Is there a more appropriate with to essentially do an if/else off of whether or not the NEWEST_REPLY relationship exists off of a specific Post?