cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

mrksph
Node Clone

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.

This is the starting graph:


The graph response I want:

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
3X_c_c_cc89341aff14af2c343d44ed54ea29df70e3674d.png
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;
Comments
tard_gabriel
Ninja
Ninja

Look out for pattern comprehension

Sorry I don't have that much time but it's a good start:

MATCH (b:Base)-[:INCLUDES]->(n)
RETURN [(n)-[:PARENT_OF*]->(sn) WHERE sn.code IN [list] | sn ] AS nodes

Benoit_d
Graph Buddy

It sounds like something known...

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.

mrksph
Node Clone

How do I include only nodes NOT in the given code list?

Thanks

mrksph
Node Clone

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.

Thanks

tard_gabriel
Ninja
Ninja

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

tard_gabriel
Ninja
Ninja

You can also use the FOREACH clause, to traverse and tag them with a SET clause so you can process them differently later on in future query.

Version history
Last update:
‎09-16-2021 09:57 AM
Updated by:
Contributors