Use of WITH clause to declare variables;

I've been using the WITH clause to decalre variables for later use such as...
WITH 'inherits from>' AS caption
MATCH (bv:Vertex {name:'«Root»'})
MATCH (iv:Vertex {name:'Datastore'})
MATCH (abv:ArcBase {name:'INHERITANCE'})
MERGE (iv)-[ibi:INHERITANCE {name:iv.name+'-'+abv.name+'->'+bv.name}]->(bv)
ON CREATE
SET ibi.caption=caption,
ibi.originName=iv.name, ibi.originUUID=iv.uuid,
ibi.destinationName=bv.name, ibi.destinationUUID=bv.uuid
ON MATCH
SET ibi.caption=caption,
ibi.originName=iv.name, ibi.originUUID=iv.uuid,
ibi.destinationName=bv.name, ibi.destinationUUID=bv.uuid
;
Is this an appropriate use of the clause? If so, why does the above version work, but
MATCH (bv:Vertex {name:'«Root»'})
MATCH (iv:Vertex {name:'Datastore'})
MATCH (abv:ArcBase {name:'INHERITANCE'})
WITH 'inherits from>' AS caption
MERGE (iv)-[ibi:INHERITANCE {name:iv.name+'-'+abv.name+'->'+bv.name}]->(bv)
ON CREATE
SET ibi.caption=caption,
ibi.originName=iv.name, ibi.originUUID=iv.uuid,
ibi.destinationName=bv.name, ibi.destinationUUID=bv.uuid
ON MATCH
SET ibi.caption=caption,
ibi.originName=iv.name, ibi.originUUID=iv.uuid,
ibi.destinationName=bv.name, ibi.destinationUUID=bv.uuid
;
i.e. moving the WITH clause to below the matches cause the subsequent MERGE to fail?

TIA,
Paolo

The with 'with' clauses passes variables to the next phase of the query. In your second example, your 'with' clause only defines 'caption', so all the variables you defined before hand go out of scope following the 'with' clause. You need to do something like the following:

with iv, abv, bv, 'inherits from>' AS caption

Note, 'with' can do more than define variables. It can also be used to group and aggregate/collect data

Thanks, @glilienfield,
We observed the behaviour you described and surmised that was the reason. But we didn't know... Now, we do!

Paolo

@pcantoni

further described in the doc at WITH - Cypher Manual and

It is important to note that WITH affects variables in scope. Any variables
 not included in the WITH clause are not carried over to the rest of the 
query. The wildcard * can be used to include all variables that are 
currently in scope.

note the link to doc is for Neo4j 5.x doc. Now it should be the same for prior versions as well but as version was never described in the original post.

1 Like

Thanks, @dana_canzano; I'm now using Neo4j 5.x so, all good!

Paolo