How to match objects without paths to specific nodes?

Hi, I always struggle to query/model things like this effectively:

match (a:A)-[:REL1]->(b:B)
where b.prop in range ( x, y )
and not (
    where c.start < $val < c.end

I know that construct/syntax isn't valid, but is there a way to do this? "Find As which are connected to specific Bs but which are not connected to Cs which fit a particular predicate". How do you do the "where" clause of the "without-this-path" section?

Alternatively, is there a way to model the nodes and relationships differently so this doesn't come up?


For this situation you can use an OPTIONAL MATCH followed by a WITH ... WHERE where you filter to only results where the newly introduced variable is null:

match (a:A)-[:REL1]->(b:B)
where b.prop in range ( x, y )  // these need to be in scope first
optional match  (a)-[:REL2]->(c:C)
where c.start < $val < c.end
with a, b
where c = null

We do have some Cypher improvements that should come with 4.0 to strengthen our ability to more concisely handle these WHERE NOT <pattern> WHERE checks.

Hi Andrew, thanks very much! Didn't think of doing it that way round, that's very helpful.

Cypher updates sound good. It'll probably be a long time before we'll be able to move to 4.x as we'll have to rewrite swathes of application code due to the removal of the REST API and other changes (not least neo4j-shell going away). So this is a good trick to know, thanks :-)

Hey @andrew.bowman, FYI I just found this really useful in several other places than the one that I originally asked it about. Super helpful, thanks! :+1: