Jack Daniel
Jack Daniel

Reputation: 2611

Neo4j - How to execute Nested query

I have to execute a query conditionally inside the CASE and assign some value to the temporary variable which helps in resolving my previous question.

Here is my query to do so is returning with syntax error:

MERGE(a {word:'review'})-[r:jsim]->(b{word:"nothing"})
ON CREATE set r.temp = false
ON MATCH set r.temp = true
CASE{r.val}  
   WHEN {r.temp} 
       THEN [MATCH (a)-[s]->(b{word:"equal"})
             SET r.val = s.val  
            ]
WITH r, r.temp AS result
REMOVE r.temp
RETURN result

My syntax error is:

Invalid input 'A': expected 'r/R' (line 4, column 2 (offset: 112))
"CASE r.temp "
  ^

My updated query after suggestions:

MERGE(a {word:'review'})-[r:jsim]->(b{word:"nothing"})
ON CREATE set r.temp = false
ON MATCH set r.temp = true
WITH r, CASE r.val WHEN r.temp THEN [MATCH (a)-[s]->(b {word:"equal"}) RETURN s.val] ELSE [] END as toDo
UNWIND toDo as val
SET r.val = head(val)
WITH r, r.temp AS result,s
REMOVE r.temp
RETURN result

Please help me out debugging this.

Upvotes: 0

Views: 731

Answers (3)

cybersam
cybersam

Reputation: 66999

Does this query work for your use case?

OPTIONAL MATCH (a { word:'review' })-[r:jsim]->(b { word:"nothing" })
WITH a, r, b, (r IS NOT NULL) AS result
OPTIONAL MATCH (a)-[s]->({ word:"equal" })
FOREACH (x IN CASE
         WHEN r IS NULL THEN [1]
         ELSE [] END | 
         CREATE ({ word:'review' })-[:jsim]->({ word:"nothing" }))
FOREACH (y IN CASE
         WHEN s IS NOT NULL THEN [1]
         ELSE [] END | 
         SET r.val = s.val)
RETURN result;

If the first OPTIONAL MATCH fails to find a match, then the second OPTIONAL MATCH should not hit the DB, since a would be NULL.

The first FOREACH would only do a CREATE if the first OPTIONAL MATCH fails. This mimics the MERGE behavior.

The second FOREACH would only set the r.val value if both OPTIONAL MATCH clauses find matches.

Upvotes: 0

Christophe Willemsen
Christophe Willemsen

Reputation: 20185

There are multiple things here :

a) When setting multiple values on an entity (node/rel), you need a comma , for separating them. So here you would need a comma after set r.temp = true

b) As mentioned by logisima, the workflow of a case is

CASE
 WHEN ..
 THEN ..
 ELSE ..
END

However, the {} are for example purposes, here you don't need to enclose your variable in {}

c) You can not do queries in CASE steps, a workaround is to build a virtual collection for it. I think for your use case this should do the trick :

MERGE(a {word:'review'})-[r:jsim]->(b{word:"nothing"})
ON CREATE set r.temp = false
ON MATCH set r.temp = true
WITH r, CASE r.val WHEN r.temp THEN [a] ELSE [] END as toDo
UNWIND toDo as a
MATCH (a)-[s]->(b {word:"equal"})
SET r.val = s.val
WITH r, r.temp AS result
REMOVE r.temp
RETURN result

So, the achievement here, is when the CASE condition is true, you will have a collection with the node a in it, when false then an empty collection. Which means that the empty will work only on the non-empty collection.

Upvotes: 1

logisima
logisima

Reputation: 7458

Your CASE statement is wrong :

CASE {var}
  WHEN {value} THEN [something]
  WHEN {value2} THEN [something]
  ELSE [something]
END

Moreover, I can't understand the meaning of your case, there is only one condition.

Upvotes: 1

Related Questions