I'm stuck writing a Cypher query that would allow me to find all nodes which their code are NOT included in a given list. I've tried searching for pattern negation, node negation, exclude in path with no success.
Let's assume I have a list of codes (even though this list one has 1 element): ["1V2ZG"]
I'd like to build a Cypher query that would return every child of ARNOG node which is NOT in the above list.
I'd like the query to return only the "ARNOG" node if the code list contains BOTH of its children ("Y6JPG", "1V2ZG") OR return No results
The query I'm using is returning all nodes which is not what I want:
MATCH
(excl:Client)<-[:PARENT_OF*]-(n:Client:Group),
path=(b:BaseHierarchy)-[:INCLUDES]->(n)-[:PARENT_OF*]->(inc:Client)
WHERE excl.code IN ['1V2ZG'] AND n.code = 'ARNOG'
WITH b,
nodes(path) as nodes, relationships(path) as relationships
RETURN b,
apoc.coll.toSet(apoc.coll.flatten(collect(relationships))) as relationships,
apoc.coll.toSet(apoc.coll.flatten(collect(nodes))) as nodes;
It seems to work until you try to get the path around 'n'. I don't understand why, but I get the same result.
May be you can have a try in isolating the 'n' in a first match
MATCH (b:BaseHierarchy)-[:INCLUDES]-> (client:Client)->[:PARENT_OF]-(n:Client:Group)
WHERE client.code = 'ARNOG' and not n.name in ['1V2ZG', '1V3ZG']
WITH incl, client, n
MATCH path = (b)-[:INCLUDES]->(client)->[:PARENT_OF]-(n)->[:PARENT_OF*]-(inc:Client:Group)
WITH b, nodes(path) as nodes, relationships(path) as relationships
RETURN b,
apoc.coll.toSet(apoc.coll.flatten(collect(relationships))) as relationships,
apoc.coll.toSet(apoc.coll.flatten(collect(nodes))) as nodes;
Pay attention that this solution assumes that there is at least one 'inc' after 'n', which seems to match your case.
Hi Benoit, I just remember you answered my previous question which was almost exactly like this one.
The thing is if the given list contains both codes ("1V2ZG" and "Y6JPG") the returning graph contains both of them, which is not what I want. If the list only contains 1 of them, the result is what I expect, containing the OTHER element.
Oops, indeed my proposition was the opposite.
Slight modification, the list comprehension will return a list of the nodes who fits with your criteria. I know it's not a complete answer but it's almost.
MATCH (b:Base)-[:INCLUDES]->(n)
RETURN [(n)-[:PARENT_OF*]->(sn) WHERE NOT sn.code IN [list] | sn ] AS nodes