neo4j - declare variables that are available for node creation in FOREACH clause and also for the RETURN clause

295 views Asked by At

I'm working on neo4j graph with the following labels: Store, User, Product

the relationships are: (store)-[:OF]->(user), (product)-[:OF]->(user), (store)-[:SELL]->(product)

when adding or updating a store, products can be added, updated, attached or removed from the store. update can be done only if the product has no attachment to other store.

I have the following adding Store query which is working:

OPTIONAL MATCH (user: User {id: $userId} )
CREATE (store:Store)-[:OF]->(user)
SET store = $store
WITH store, user
OPTIONAL MATCH (p: Product {id: "hu1"})-[:OF]->(user)  
WITH store, p,  
CASE WHEN NOT (:Store)-[:SELL]->(p) OR                 
(:Store {id: '12asd'})-[:SELL]->(p) THEN [1]      
ELSE [] END as array              
FOREACH(
    x in array |              
    MERGE (p)-[:OF]->(user)          
    ON MATCH SET p += $product1         
    ON CREATE SET p = $product1         
    MERGE (store)-[:SELL]->(p)         
) 
RETURN store, p

(it might seem weird that one of my condition is checking the store id, when i just created it, but this query in the code handles more situations when it is needed, and i don't wont to trouble with the whole code)

the modification needed is moving the creation of the store to the FOREACH statement because, i don't wont to create the store if one of the products didn't pass one of the CASE conditions.

i tried moving the store creation inside the FOREACH statement using MERGE -

OPTIONAL MATCH (user: User {id: $userId} ) 
WITH user
OPTIONAL MATCH (p: Product {id: "1"})-[:OF]->(user)  
WITH p,  
CASE WHEN NOT (:Store)-[:ON]->(p) OR                 
(:Store {id: 'st'})-[:ON]->(p) 
THEN [1]      
ELSE [] END as array              
FOREACH(
    x in array |              
    MERGE (p)-[:OF]->(user)          
    ON MATCH SET p += $product1         
    ON CREATE SET p = $product1         
    MERGE (store:Store {id: 'st'})
    ON MATCH SET store += $store         
    ON CREATE SET store = $store         
    MERGE (store)-[:ON]->(p)         
) 
RETURN store, p 

but i got this error:

Neo4jError: Variable store not defined

pointing on the store variable in the RETURN statement.

i tried adding another WITH statement between the FOREACH and the RETURN but i got the same error only pointing on the store variable in the WITH clause.

how can i declare a variable out side of the FOREACH clause so i could create node for it in the FOREACH and also use it in the RETURN ?

1

There are 1 answers

1
Tomaž Bratanič On

Try to declare your parameters outside the FOREACH statement:

OPTIONAL MATCH (user: User {id: $userId} ) 
WITH user
OPTIONAL MATCH (p: Product {id: "1"})-[:OF]->(user)  
WITH p,  
     CASE WHEN NOT (:Store)-[:ON]->(p) OR                 
                   (:Store {id: 'st'})-[:ON]->(p) 
                   THEN [1] ELSE [] END as array,
     $store as store,
     $product1 as product1              
FOREACH(
    x in array |              
    MERGE (p)-[:OF]->(user)          
    ON MATCH SET p += product1         
    ON CREATE SET p += product1         
    MERGE (s:Store {id: 'st'})
    ON MATCH SET s += store         
    ON CREATE SET s += store         
    MERGE (s)-[:ON]->(p)         
) 
RETURN store, p