juanbits
juanbits

Reputation: 347

Exclude nodes using WHERE not works

I have an error when i try to exclude nodes using MATCH&WHERE

I have the next nodes & rrlationships:

MERGE (a1:accz {id: 1}) 
MERGE (a2:accz {id: 2}) 
MERGE (a3:accz {id: 3}) 
MERGE (a4:accz {id: 4}) 
MERGE (a5:accz {id: 5}) 
MERGE (i1:itemz {id: 1}) 
MERGE (i2:itemz {id: 2}) 
MERGE (i3:itemz {id: 3}) 
MERGE (i4:itemz {id: 4}) 
MERGE (a1)-[:AUTHOR]->(i1) 
MERGE (a2)-[:AUTHOR]->(i2) 
MERGE (a3)-[:AUTHOR]->(i1) 
MERGE (a3)-[:AUTHOR]->(i3) 
MERGE (a4)-[:AUTHOR]->(i4) 
MERGE (a4)-[:AUTHOR]->(i5) 
MERGE (a4)-[:AUTHOR]->(i5) 
MERGE (a5)-[:AUTHOR]->(i2) 
MERGE (a5)-[:AUTHOR]->(i5)

When i execute (I include in a explicit way the items with which the accz need have a relationship):

MATCH (a:accz)-[:AUTHOR]->(i:itemz) WHERE ({id: i.id} IN [({id: 3}), ({id: 4})]) RETURN a

i got the accz nodes (3,4,5), and is ok. But then i exclude some nodes using WHERE, like the next query:

MATCH (a:accz)-[:AUTHOR]->(i:itemz) WHERE ({id: i.id} IN [({id: 3}), ({id: 4})]) AND (NOT (a)-[:AUTHOR]->(:itemz {id:5})) RETURN a

but i continue getting the accz node id:5, this should be excluded because the acc{id:5} is AUTHOR of (:itemz {id:5})

what im doing wrong?

Upvotes: 0

Views: 47

Answers (1)

cybersam
cybersam

Reputation: 66999

The odd behaviors seen in your example would seem like bugs, but can be explained (after some careful thought). One conclusion, after all is said and done, is that you should avoid using unbound nodes in a MERGE clause.

The odd behaviors

Your creation query has no MERGE clause to create the itemz node i5. That is, this clause is missing: MERGE (i5:itemz {id: 5}).

  1. Therefore, it would seem like the 2 MERGE (a4)-[:AUTHOR]->(i5) clauses should result in the creation of a new unlabelled i5 node with no properties -- but no such node is created!

  2. And it would also seem like the MERGE (a5)-[:AUTHOR]->(i5) clause should result in a relationship with that new i5 -- but instead it unexpectedly results in a relationship with i4!

Explanation

This snippet of code causes the odd behavior (I have added comments to clarify):

MERGE (a4)-[:AUTHOR]->(i4) // Makes sure `(a4)-[:AUTHOR]->(i4)` relationship exists
MERGE (a4)-[:AUTHOR]->(i5) // Matches above relationship, so creates `i5` and binds it to `i4`!
MERGE (a4)-[:AUTHOR]->(i5) // Matches same relationship, so nothing is done.

So, after the snippet is executed, i4 and i5 are bound to the same node. This explains the odd behaviors.

Conclusion

To avoid unexpected results, you should avoid using unbound nodes in MERGE clauses.

If your creation query had included a MERGE (i5:itemz {id: 5}) clause before the relationships were created, then your queries would have worked reasonably. The result of the first query would contain accz nodes 3 and 4, and the result of the second query would only contain 3.

By the way, ({id: i.id} IN [({id: 3}), ({id: 4})]) can be greatly simplified to just i.id IN [3, 4].

Upvotes: 1

Related Questions