WHERE
The WHERE clause is used to filter the results of MATCH patterns.
Basic Filtering#
Property Comparison#
MATCH (u:User)
WHERE u.age > 25
RETURN u
Multiple Conditions#
MATCH (u:User)
WHERE u.age > 25 AND u.city = 'New York'
RETURN u
OR Conditions#
MATCH (u:User)
WHERE u.age < 18 OR u.age > 65
RETURN u
Comparison Operators#
-- Equality
WHERE u.name = 'Alice'
-- Inequality
WHERE u.age <> 30
-- Numeric comparison
WHERE u.age > 25
WHERE u.age >= 18
WHERE u.age < 65
WHERE u.age <= 100
-- String comparison
WHERE u.name > 'A' -- Alphabetical
String Matching#
Exact Match#
WHERE u.name = 'Alice'
Case-Insensitive#
WHERE toLower(u.name) = 'alice'
Contains#
WHERE u.name CONTAINS 'Ali'
Starts With#
WHERE u.name STARTS WITH 'Al'
Ends With#
WHERE u.name ENDS WITH 'ce'
Regular Expressions#
WHERE u.email =~ '.*@example\\.com'
NULL Checks#
IS NULL#
WHERE u.phone IS NULL
IS NOT NULL#
WHERE u.email IS NOT NULL
List Operations#
IN Operator#
WHERE u.city IN ['New York', 'Los Angeles', 'Chicago']
List Membership#
WHERE 'Admin' IN u.roles
Range Checks#
-- Age between 25 and 35
WHERE u.age >= 25 AND u.age <= 35
-- Using IN for discrete values
WHERE u.age IN [25, 26, 27, 28, 29, 30]
Pattern Filters#
Relationship Existence#
MATCH (u:User)
WHERE (u)-[:KNOWS]->(:User {name: 'Alice'})
RETURN u
NOT Pattern#
MATCH (u:User)
WHERE NOT (u)-[:KNOWS]->(:User {name: 'Bob'})
RETURN u
Path Existence#
MATCH (u:User), (target:User {name: 'Alice'})
WHERE (u)-[:KNOWS*1..3]->(target)
RETURN u
Boolean Logic#
NOT#
WHERE NOT u.age > 65
WHERE NOT (u)-[:KNOWS]->(:User)
Complex Expressions#
WHERE (u.age > 25 AND u.city = 'NYC') OR (u.age < 18 AND u.student = true)
Property Existence#
-- Check if property exists
WHERE EXISTS(u.email)
-- Check if property doesn't exist
WHERE NOT EXISTS(u.phone)
Using Parameters#
MATCH (u:User)
WHERE u.age > $minAge AND u.city = $city
RETURN u
Label Checking#
MATCH (n)
WHERE n:User OR n:Admin
RETURN n
Filtering Relationships#
MATCH (u:User)-[r:KNOWS]->(f:User)
WHERE r.since > '2020-01-01'
RETURN u, f
Common Patterns#
Active Users#
MATCH (u:User)
WHERE u.lastLogin > datetime() - duration('P7D')
AND u.active = true
RETURN u
Users with Friends#
MATCH (u:User)
WHERE EXISTS((u)-[:KNOWS]->(:User))
RETURN u
Exclude Self-Loops#
MATCH (a:User)-[:KNOWS]->(b:User)
WHERE a <> b
RETURN a, b
Time Range#
MATCH (p:Post)
WHERE p.created >= datetime('2024-01-01')
AND p.created < datetime('2024-02-01')
RETURN p
Performance Tips#
-
Use Indexed Properties
cypher -- Fast with index on email WHERE u.email = '[email protected]' -
Most Selective Filters First ```cypher -- Good: Most selective first WHERE u.email = '[email protected]' AND u.active = true
-- Less optimal WHERE u.active = true AND u.email = '[email protected]' ```
- Avoid Property Functions in Filters ```cypher -- Good: Direct comparison WHERE u.email = '[email protected]'
-- Bad: Function prevents index use WHERE toUpper(u.email) = '[email protected]' ```
- Use Parameters ```cypher -- Good: Query plan cached WHERE u.age > $minAge
-- Bad: Reparse every time WHERE u.age > 25 ```
Next Steps#
- Match patterns with MATCH
- Select output with RETURN
- Sort results with ORDER BY
- Read Cypher Introduction