Skip to content

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

  1. Use Indexed Properties

    -- Fast with index on email
    WHERE u.email = 'alice@example.com'
    

  2. Most Selective Filters First

    -- Good: Most selective first
    WHERE u.email = 'alice@example.com' AND u.active = true
    
    -- Less optimal
    WHERE u.active = true AND u.email = 'alice@example.com'
    

  3. Avoid Property Functions in Filters

    -- Good: Direct comparison
    WHERE u.email = 'ALICE@EXAMPLE.COM'
    
    -- Bad: Function prevents index use
    WHERE toUpper(u.email) = 'ALICE@EXAMPLE.COM'
    

  4. Use Parameters

    -- Good: Query plan cached
    WHERE u.age > $minAge
    
    -- Bad: Reparse every time
    WHERE u.age > 25
    

Next Steps