Taylor F
Taylor F

Reputation: 101

Using multiple variables in Neo4j CALL{ WITH ...}

I have a number of nodes with properties I'd like to convert into relationships and relationship properties. Ideally, I'd like to do many of these at once using UNWIND ["prop1", "prop2", ...] with CALL { WITH unwound_prop ...}, but I am running into trouble when executing the entire CALL structure.

For instance, if I have a couple people nodes with some properties:

create (n:person {name: "Tabitha", lunch: "salad", dinner:"steak"});
create (n:person {name: "Tony", lunch: "salad", dinner:"steak"});
create (n:person {name: "Sam", lunch: "spaghetti", dinner:"pizza"});
create (l:meal {name: "lunch"});
create (l:meal {name: "dinner"});

I could use the following query to create a separate relationship with all these people and their lunch meal (which works):

match (n:person) with n
match (l:meal)
where l.name = "lunch"
and n.lunch IS NOT NULL
create (n)-[r:ATE {food:n.lunch}]->(l)
remove n.lunch;

This moves the property of the person node onto the relationship, which is what I want.

However, if I want to do this multiple times using CALL then I run into an issue:

unwind ["lunch", "dinner"] as sel_meal
call {
    with sel_meal
    match (n:person) with n
    match (l:meal)
    where l.name = sel_meal
    and n[sel_meal] IS NOT NULL
    create p=(n)-[r:ATE {food:n[sel_meal]}]->(l)
    return p as result
}
return result;

ERROR:

Neo.ClientError.Statement.SyntaxError: Variable `sel_meal` not defined (line 6, column 20 (offset: 130))
"    where l.name = sel_meal"
                    ^

It seems that using the WITH n to reduce the cardinality of person nodes selected overrides the WITH sel_meal clause, so I can't use the unwound variable. Is there a way to include both? A better way to correctly select these nodes? Or a better way to unwind multiple variables at once into relationships (FOREACH doesn't seem to be very useful here either).

Upvotes: 0

Views: 1098

Answers (1)

Tomaž Bratanič
Tomaž Bratanič

Reputation: 6534

You have a WITH clause in between where you don't include the sel_meal variable in scope:

match (n:person) with n

The whole query would look like:

unwind ["lunch", "dinner"] as sel_meal
call {
    with sel_meal
    match (n:person) 
    with n, sel_meal
    match (l:meal)
    where l.name = sel_meal
    and n[sel_meal] IS NOT NULL
    create p=(n)-[r:ATE {food:n[sel_meal]}]->(l)
    return p as result
}
return result;

Upvotes: 1

Related Questions