Hi,
I need to do some Update operations that creating nonexistent values should be supported, too.
For example, suppose we have relations like (a: A)-[r: Contains]->(b:B) and I need a command template to support both updating and creating new relationships. I need something like the following:
MERGE (a:A {name: 'foo'})-[r :CONTAINS]->(b:B {name: 'bar' }) WHERE a.validTo IS NULL AND r.validTo IS NULL SET b.lastName = 'new_Value'
Using the above query I can update properties for already existent relations and also create new relations, if not exists. But the problem is WHERE
closures can not be used in MERGE
queries. So I wanted to know is there any way to use WHERE
clousures in MERGE
queries?
Hi Ahoora08,
To apply a filter (WHERE clause) after MERGE you need to introduce a projection (WITH) so your query becomes:
MERGE (a:A {name: ‘foo’})-[r :CONTAINS]->(b:B {name: ‘bar’ })
WITH a AS a, r AS r, b AS b
WHERE a.validTo IS NULL AND r.validTo IS NULL
SET b.lastName = ‘new_Value’
But it seems like currently we’ve got a bug with regard to filter placement.
As you can see:
GRAPH.EXPLAIN g “MERGE (a:A {name: ‘foo’})-[r :CONTAINS]->(b:B {name: ‘bar’ }) WITH a AS a, r AS r, b AS b WHERE a.validTo IS NULL AND r.validTo IS NULL SET b.lastName = ‘new_Value’”
- “Update”
- " Project"
- " Merge"
- " Filter"
- " Conditional Traverse | (a:A)-[r:CONTAINS]->(b:B)"
- " Filter"
- " Node By Label Scan | (a:A)"
- " MergeCreate"
The filter are positioned too early.
As a temporary workaround let me suggest the following:
GRAPH.EXPLAIN g “MERGE (a:A {name: ‘foo’})-[r :CONTAINS]->(b:B {name: ‘bar’ }) WITH 1 AS x, a AS a, r AS r, b AS b WHERE x=1 OR (a.validTo IS NULL AND r.validTo IS NULL) SET b.lastName = ‘new_Value’”
- “Update”
- " Filter"
- " Project"
- " Merge"
- " Filter"
- " Conditional Traverse | (a:A)-[r:CONTAINS]->(b:B)"
- " Filter"
- " Node By Label Scan | (a:A)"
- " MergeCreate"
Which places the filter at the right position
Hi SWilly22 and thanks for your reply,
I tried the suggested approach. In case of an update, it works as desire and update properties in already existent nodes A
and B
. But in the case of creating (the B doesn’t already exist), it creates a new relationship with new two nodes A
and B
but I need it only to add the new node B
and create relation with the already existent node A
.
I checked the EXPLAIN command on my Redis env and I got the same result as yours. In addition, I’m executing GRAPG.QUERY
commands using the Lua
script and redis.call
method.
MERGE is all or nothing, meaning either the entire pattern exists in the graph or the entire path is created with the exception of already bounded variables, if you require the A node to exists prior to MERGE pattern i.e. A is bounded, then either MERGE on A or MATCH on A.
MATCH (a:A {name: ‘foo’})
MERGE (a)-[r :CONTAINS]->(b:B {name: ‘bar’ })
…
1 Like