Prev |  | Next

## 15.11. Where

If you need filtering apart from the pattern of the data that you are looking for, you can add clauses in the `WHERE` part of the query.

Figure 15.4. Graph

### 15.11.1. Boolean operations

You can use the expected boolean operators `AND` and `OR`, and also the boolean function `NOT()`.

Query.

    START n=node(3, 1)
    WHERE (n.age < 30 and n.name = "Tobias") or not(n.name = "Tobias")
    RETURN n

This will return both nodes in the start clause.

Result

n
2 rows
0 ms
`Node[3]{name:"Andres",age:36,belt:"white"}`
`Node[1]{name:"Tobias",age:25}`

### 15.11.2. Filter on node property

To filter on a property, write your clause after the `WHERE` keyword. Filtering on relationship properties works just the same way.

Query.

    START n=node(3, 1)
    WHERE n.age < 30
    RETURN n

The "`Tobias`" node will be returned.

Result

n
1 row
1 ms
`Node[1]{name:"Tobias",age:25}`

### 15.11.3. Regular expressions

You can match on regular expressions by using `=~ "regexp"`, like this:

Query.

    START n=node(3, 1)
    WHERE n.name =~ 'Tob.*'
    RETURN n

The "`Tobias`" node will be returned.

Result

n
1 row
0 ms
`Node[1]{name:"Tobias",age:25}`

### 15.11.4. Escaping in regular expressions

If you need a forward slash inside of your regular expression, escape it. Remember that back slash needs to be escaped in string literals

Query.

    START n=node(3, 1)
    WHERE n.name =~ 'Some\\/thing'
    RETURN n

No nodes match this regular expression.

Result

n
0 row
0 ms
`(empty result)`

### 15.11.5. Case insensitive regular expressions

By pre-pending a regular expression with `(?i)`, the whole expression becomes case insensitive.

Query.

    START n=node(3, 1)
    WHERE n.name =~ '(?i)ANDR.*'
    RETURN n

The node with name "`Andres`" is returned.

Result

n
1 row
1 ms
`Node[3]{name:"Andres",age:36,belt:"white"}`

### 15.11.6. Filtering on relationship type

You can put the exact relationship type in the `MATCH` pattern, but sometimes you want to be able to do more advanced filtering on the type. You can use the special property `TYPE` to compare the type with something else. In this example, the query does a regular expression comparison with the name of the relationship type.

Query.

    START n=node(3)
    MATCH (n)-[r]->()
    WHERE type(r) =~ 'K.*'
    RETURN r

This returns relationships that has a type whose name starts with K.

Result

r
2 rows
0 ms
`:KNOWS[0] {}`
`:KNOWS[1] {}`

### 15.11.7. Property exists

To only include nodes/relationships that have a property, use the `HAS()` function and just write out the identifier and the property you expect it to have.

Query.

    START n=node(3, 1)
    WHERE has(n.belt)
    RETURN n

The node named "`Andres`" is returned.

Result

n
1 row
0 ms
`Node[3]{name:"Andres",age:36,belt:"white"}`

### 15.11.8. Default true if property is missing

If you want to compare a property on a graph element, but only if it exists, use the nullable property syntax. You can use a question mark if you want missing property to return true, like:

Query.

    START n=node(3, 1)
    WHERE n.belt? = 'white'
    RETURN n

This returns all nodes, even those without the belt property.

Result

n
2 rows
0 ms
`Node[3]{name:"Andres",age:36,belt:"white"}`
`Node[1]{name:"Tobias",age:25}`

### 15.11.9. Default false if property is missing

When you need missing property to evaluate to false, use the exclamation mark.

Query.

    START n=node(3, 1)
    WHERE n.belt! = 'white'
    RETURN n

No nodes without the belt property are returned.

Result

n
1 row
0 ms
`Node[3]{name:"Andres",age:36,belt:"white"}`

### 15.11.10. Filter on null values

Sometimes you might want to test if a value or an identifier is `null`. This is done just like SQL does it, with `IS NULL`. Also like SQL, the negative is `IS NOT NULL`, although `NOT(IS NULL x)` also works.

Query.

    START a=node(1), b=node(3, 2)
    MATCH a<-[r?]-b
    WHERE r is null
    RETURN b

Nodes that Tobias is not connected to are returned.

Result

b
1 row
1 ms
`Node[2]{name:"Peter",age:34}`

### 15.11.11. Filter on patterns

Patterns are expressions in Cypher, expressions that return a collection of paths. Collection expressions are also predicates — an empty collection represents `false`, and a non-empty represents `true`.

So, patterns are not only expressions, they are also predicates. The only limitation to your pattern is that you must be able to express it in a single path. You can not use commas between multiple paths like you do in `MATCH`. You can achieve the same effect by combining multiple patterns with `AND`.

Note that you can not introduce new identifiers here. Although it might look very similar to the `MATCH` patterns, the `WHERE` clause is all about eliminating matched subgraphs. `MATCH a-[*]->b` is very different from `WHERE a-[*]->b`; the first will produce a subgraph for every path it can find between `a` and `b`, and the latter will eliminate any matched subgraphs where `a` and `b` do not have a directed relationship chain between them.

Query.

    START tobias=node(1), others=node(3, 2)
    WHERE tobias<--others
    RETURN others

Nodes that have an outgoing relationship to the "`Tobias`" node are returned.

Result

others
1 row
1 ms
`Node[3]{name:"Andres",age:36,belt:"white"}`

### 15.11.12. Filter on patterns using NOT

The `NOT()` function can be used to exclude a pattern.

Query.

    START persons=node(*), peter=node(2)
    WHERE not(persons-->peter)
    RETURN persons

Nodes that do not have an outgoing relationship to the "`Peter`" node are returned.

Result

persons
2 rows
1 ms
`Node[1]{name:"Tobias",age:25}`
`Node[2]{name:"Peter",age:34}`

### 15.11.13. IN operator

To check if an element exists in a collection, you can use the `IN` operator.

Query.

    START a=node(3, 1, 2)
    WHERE a.name IN ["Peter", "Tobias"]
    RETURN a

This query shows how to check if a property exists in a literal collection.

Result

a
2 rows
0 ms
`Node[1]{name:"Tobias",age:25}`
`Node[2]{name:"Peter",age:34}`

Copyright © 2013 Neo Technology

Prev | Up | Next
| Home |