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 WITH
MATCH (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 path´s 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 Predicated 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