I'm trying to implement the logic in Cypher where, based on a particular condition (CASE
Statement), I would create some nodes and relationships; the code is as below
MATCH (g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block)
WHERE g.game_id='G222' and u.email_id = '[email protected]' and b1.block_id='16'
SET r1.status='Skipped', r1.enddate=20141225
WITH u, b2,b1, g, r1
SET b1.test = CASE b2.fork
WHEN 'y' THEN
MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2 {fork:'fail'}) RETURN 1
ELSE
MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2) RETURN 2
END
WITH u, g
MATCH (u)-[:TIME]->(h:Time)<-[:TIME]-(g)
SET h.after = 0
SET h.before = h.before + 1
In this query there is a merge
statement within the WHEN 'y' THEN
, this query throws an error:
Invalid input ']': expected whitespace or a relationship pattern (line 7, column 82) "MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2 {fork:'fail'}) RETURN 1"
Basically I'm trying to create a relationship based on a property i.e. a MERGE
within a CASE
statement, I tried different ways to get this working like doing a return so that case when returns some value etc. but nothing worked so far.
What could be the issue with this query?
MERGE either matches existing nodes and binds them, or it creates new data and binds that. It's like a combination of MATCH and CREATE that additionally allows you to specify what happens if the data was matched or created.
MERGE acquires locks on nodes and relationships in the pattern when resulting in pattern creation. When MERGE fails to find an existing pattern, it will acquire locks on all bound nodes and relationships in the pattern before creating the missing elements of the pattern.
You can merge a node in the database based on the label using the MERGE clause. If you try to merge a node based on the label, then Neo4j verifies whether there exists any node with the given label. If not, the current node will be created.
With UNWIND , you can transform any list back into individual rows.
To do conditional write operations you need to use the FOREACH
trick. Using CASE
you either return a one element array or a empty one. FOREACH
iterates over the CASE
expression and therefore conditionally executes the action. If you want an ELSE
part as well you need to have a another FOREACH
using the inverse condition in the CASE
. As an example, instead of
WHEN 'y' THEN
MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2 {fork:'fail'}) RETURN 1
ELSE
MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2) RETURN 2
END
use
FOREACH(ignoreMe IN CASE WHEN 'y' THEN [1] ELSE [] END |
MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2 {fork:'fail'})
)
FOREACH(ignoreMe IN CASE WHEN NOT 'y' THEN [1] ELSE [] END |
MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2)
)
See also Mark's blog post on this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With