WHERE
The WHERE clause is not a clause in its own right — rather, it is subclause used with MATCH, OPTIONAL MATCH, and WITH clauses.
When used with MATCH and OPTIONAL MATCH, WHERE adds constraints to the patterns described.
It should not be seen as a filter after the matching is finished.
In the case of multiple MATCH / OPTIONAL MATCH clauses, the predicate in WHERE is always a part of the patterns in the directly preceding MATCH / OPTIONAL MATCH.
Both results and performance may be impacted if WHERE is put inside the wrong MATCH clause.
When used after WITH, WHERE simply filters the results.
For more uses of WHERE, see Predicates.
|
Example graph
The following graph is used for the examples below:
To recreate the graph, run the following query in an empty Neo4j database:
CREATE (andy:Swedish:Person {name: 'Andy', age: 36}),
(timothy:Person {name: 'Timothy', age: 38}),
(peter:Person {name: 'Peter', age: 35}),
(lisa:Person {name: 'Lisa', age: 48}),
(john:Person {name: 'John', age: 40}),
(susan:Person {name: 'Susan', age: 32}),
(andy)-[:KNOWS {since: 2012}]->(timothy),
(andy)-[:KNOWS {since: 1999}]->(peter),
(peter)-[:KNOWS {since: 2005}]->(lisa),
(lisa)-[:KNOWS {since: 2010}]->(john),
(john)-[:KNOWS {since: 2021}]->(susan)
Basic filtering
MATCH (n)
WHERE n:Swedish
RETURN n.name AS name
| name |
|---|
|
|
MATCH (n:Person)
WHERE n.age < 35
RETURN n.name AS name, n.age AS age
| name | age |
|---|---|
|
|
Rows: 1 |
|
MATCH (:Person {name:'Andy'})-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f.name AS oldFriend
| oldFriend |
|---|
|
|
Filter on dynamic properties
To filter on a property using a dynamically computed name, use square brackets []:
{
"propname": "age"
}
MATCH (n:Person)
WHERE n[$propname] > 40
RETURN n.name AS name, n.age AS age
| name | age |
|---|---|
|
|
Rows: 1 |
|
Using WHERE after WITH
WITH can be used to manipulate the output of a clause before it is passed on to subsequent query parts.
Once such a manipulation has occurred, the original clause output is not available to subsequent clauses.
For example, in the below query, WITH manipulates the output of the preceding MATCH in such a way that the succeeding RETURN no longer has access to the variable n declared in the MATCH.
WITH only retains explicitly listed variables; others become inaccessibleMATCH (n:Person)
WITH n.name as name
RETURN n
The above query would work if the RETURN clause instead referenced the name variable produced by WITH.
However, because WHERE is a subclause and not a clause, its scope is not limited by immediately preceding WITH clauses.
WHERE is not limited by an immediately preceding WITHMATCH (n:Person)
WITH n.name as name
WHERE n.age = 38
RETURN name
| name |
|---|
|
Rows: 1 |
The name for Timothy is returned because the WHERE clause still acts as a filter on the MATCH.
However, WITH still reduces the scope for the rest of the query moving forward.
In this case, name is the only variable in scope for the RETURN clause.
Filter patterns
WHERE clauses can be added to fixed-length and variable-length patterns in order to specify additional constraints.
Fixed-length patterns
WHERE inside a node patternWITH 35 AS minAge
MATCH (a:Person WHERE a.name = 'Andy')-[:KNOWS]->(b:Person WHERE b.age > minAge)
RETURN b.name AS name
| name |
|---|
|
Rows: 1 |
When used this way, predicates in WHERE can reference the node variable that the WHERE clause belongs to, but not other elements of the MATCH pattern.
The same rule applies to pattern comprehensions:
WHERE inside a pattern comprehensionMATCH (a:Person {name: 'Andy'})
RETURN [(a)-->(b WHERE b:Person) | b.name] AS friends
| friends |
|---|
|
|
WHERE can also appear inside a relationship pattern in a MATCH clause:
WHERE inside relationship patternWITH 2000 AS minYear
MATCH (a:Person)-[r:KNOWS WHERE r.since < minYear]->(b:Person)
RETURN a.name AS person, b.name AS friend, r.since AS knowsSince
| name | friend | knowsSince |
|---|---|---|
|
|
|
Rows: 1 |
||
Relationship pattern predicates can also be used inside pattern comprehensions, where the same caveats apply:
WITH 2000 AS minYear
MATCH (a:Person {name: 'Andy'})
RETURN [(a)-[r:KNOWS WHERE r.since < minYear]->(b:Person) | r.since] AS years
| years |
|---|
|
Rows: 1 |
Variable-length patterns
If matching for variable length patterns, WHERE can only be used together with the quantified path pattern or quantified relationships syntax.
WHERE predicate inside a quantified relationshipMATCH p = (a:Person {name: "Andy"})-[r:KNOWS WHERE r.since < 2011]->{1,4}(:Person)
RETURN [n IN nodes(p) | n.name] AS paths
Note that any paths including Timothy and Susan are excluded by the WHERE predicate, since their incoming KNOWS relationships both have a since value that is higher than 2011.
| paths |
|---|
|
|
|
Rows: 3 |
For more information about using WHERE predicates in quantified path patterns, see Predicates in quantified path patterns.
WHERE is not allowed in variable-length patterns using the non-GQL compliant variable-length relationship syntax.
WHERE inside a variable-length relationshipMATCH p = (a:Person {name: 'Andy'})-[r:KNOWS*1..4 WHERE r.since < 2011]->(b:Person)
RETURN [n IN nodes(p) | n.name] AS path