Matthew
Matthew

Reputation: 604

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?

Upvotes: 0

Views: 294

Answers (2)

Matthew
Matthew

Reputation: 604

So the way I solved it was this

MATCH (a:CloudApp)-[]-(p:Policy{state: "enabled"})
WHERE (p)-[:EXCLUDE_CLOUDAPP]-(a)
WITH COLLECT(p) as excluded
MATCH (a:CloudApp)-[]-(p:Policy{state: "enabled"})
WHERE (a{id:"All"})-[]-(p:Policy{state: "enabled"})
WITH p,a,excluded
MATCH (p)-[]-(pl:Platform {id: "macOS"})
WHERE NOT (p)-[:EXCLUDE_Platform]-(pl)
WITH COLLECT(p) as included, excluded
RETURN [n IN included WHERE not n IN excluded] as list

I found the nodes I didn't want, then the ones I did want and removed the excluded ones from those using the WHERE not n IN part

Upvotes: 0

Charchit Kapoor
Charchit Kapoor

Reputation: 9284

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.

Upvotes: 1

Related Questions