Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypher Neo4J - CASE Expression with MERGE

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?

like image 363
deepesh Avatar asked Dec 20 '14 02:12

deepesh


People also ask

What does merge do in Cypher?

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.

How does merge work in Neo4j?

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.

How do I merge two nodes in Neo4j?

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.

What is unwind in Neo4j?

With UNWIND , you can transform any list back into individual rows.


Video Answer


1 Answers

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.

like image 175
Stefan Armbruster Avatar answered Oct 03 '22 05:10

Stefan Armbruster