smacdav
smacdav

Reputation: 445

Neo4j Cypher: exclude certain nodes from result

I have two queries, call them query A and query B. What I need is to get all the results of query A that are not in query B. Example:

Query A:

MATCH (m:MyNode {prop: 'value'}), (n:MyNode {prop: 'value', otherProp: (m).otherProp}
  WHERE m<>n AND shortestPath( (m)-[*]-(n) ) IS NULL
  RETURN m

Query B:

MATCH (m:MyNode)-[:SOME_RELATION]->()<-[:SOME_RELATION]-(n:MyNode {prop: 'value'})
    WHERE m.prop<>'value'
    RETURN n

These two queries return what I expect, but what I really want is everything that Query A returns that Query B does not.

I've tried a bunch of different things mostly using WHERE NONE based on what I found at https://neo4j.com/developer/kb/performing-pattern-negation/, but all I seem to be able to do is eliminate all of the results instead of just those that come from Query B.

Any suggestions?

Upvotes: 2

Views: 1185

Answers (1)

smacdav
smacdav

Reputation: 445

Of course, after asking, I found my own solution. Here's what I came up with:

Match (r:MyNode)-[:SOME_RELATION]->()<-[:SOME_RELATION]-(s:MyNode { prop: 'value' })
    WHERE r.prop<>'value'
    WITH COLLECT(s) AS excluded
MATCH (m:MyNode {prop: 'value'}), (n:MyNode {prop: 'value', otherProp: (m).otherProp})
    WITH excluded, COLLECT(m) AS included
RETURN FILTER(n IN included WHERE NOT n IN EXCLUDED)

This works for me, but I'm certainly open to more efficient solutions if anyone has one.

Upvotes: 1

Related Questions