Search code examples
neo4jcypher

Neo4j - Exclude node from results where it has a specific relationship


I'm attempting to a set of nodes (p) where they have a relationship [:INCLUDE] to a specific node (ca) identified by its ID, but I also want to make sure I exclude any (p) node that also has an [:EXCLUDE] relationship to any other (ca) node.

I've tried the below...

MATCH (a:CloudApp)-[]-(p:Policy{state: "enabled"})
WHERE (a{id:"All"})-[]-(p) OR (a{id:"b9a97804-0c6b-4d83-8b35-84bda7f8b69c"})-[]-(p)
WITH p,a
MATCH (p)-[]-(pl:Platform {id: "macOS"})
WHERE NOT (p)-[:EXCLUDE_Platform]-(pl)
WITH p,a,pl
RETURN *

Which gets me this...

enter image description here

And then tried to filter it with this...

MATCH (a:CloudApp)-[]-(p:Policy{state: "enabled"})
WHERE (a{id:"All"})-[]-(p) OR (a{id:"b9a97804-0c6b-4d83-8b35-84bda7f8b69c"})-[]-(p)
WITH p,a
MATCH (p)-[]-(pl:Platform {id: "macOS"})
WHERE NOT (p)-[:EXCLUDE_Platform]-(pl) AND NOT (p)-[:EXCLUDE_CLOUDAPP]-(a)
WITH p,a,pl
RETURN *

But this results in the same 3 (p) nodes and just excludes the (a) node where that relationship exists. I've tried a few variations on the above query and always seem to get the same result...

enter image description here

I'm guessing that this is because it just excludes that relationship and the node remains because it has another valid relationship. I'm just not sure how to achieve what I want?


Solution

  • Just remove the variable a from the condition NOT (p)-[:EXCLUDE_CLOUDAPP]-(a) and add a node label, and try this:

    MATCH (a:CloudApp)-[]-(p:Policy{state: "enabled"})
    WHERE (a{id:"All"})-[]-(p) OR (a{id:"b9a97804-0c6b-4d83-8b35-84bda7f8b69c"})-[]-(p)
    WITH p,a
    MATCH (p)-[]-(pl:Platform {id: "macOS"})
    WHERE NOT (p)-[:EXCLUDE_Platform]-(pl) AND NOT (p)-[:EXCLUDE_CLOUDAPP]-(:CloudApp)
    WITH p,a,pl
    RETURN *
    

    This basically checks whether the policy node is not linked to any CloudApp node via exclude relationship.