Type predicate expressionsIntroduced in 5.9
A type predicate expression can be used to verify the type of a variable, literal, property or other Cypher® expression.
Syntax
<expr> IS :: <TYPE>
Where <expr> is any Cypher expression and <TYPE> is a Cypher type.
For all available Cypher types, see the section on types and their synonyms.
Verify the type of a Cypher expression
UNWIND [42, true, 'abc', null] AS val
RETURN val, val IS :: INTEGER AS isInteger
| val | isInteger |
|---|---|
|
|
|
|
|
|
|
|
Rows: 4 |
|
Type predicate expressions with NOT
It is also possible to verify that a Cypher expression is not of a certain type, using the negated type predicate expression IS NOT ::.
UNWIND [42, true, 'abc', null] AS val
RETURN val, val IS NOT :: STRING AS notString
| val | notString |
|---|---|
|
|
|
|
|
|
|
|
Rows: 4 |
|
Type predicate expressions for nullIntroduced in 5.10
All Cypher types includes the null value.
Since Neo4j 5.10, type predicate expressions can be appended with NOT NULL.
This means that IS :: returns true for all expressions evaluating to null, unless NOT NULL is appended.
RETURN
NULL IS :: BOOLEAN AS isBoolean,
NULL IS :: BOOLEAN NOT NULL AS isNotNullBoolean
| isBoolean | isNotNullBoolean |
|---|---|
|
|
Rows: 1 |
|
Likewise, IS NOT :: returns false for all expressions evaluating to null, unless the type is appended with NOT NULL.
RETURN
(null + 1) IS NOT :: DATE AS isNotDate,
(null + 1) IS NOT :: DATE NOT NULL AS isNotNotNullDate
| isNotDate | isNotNotNullDate |
|---|---|
|
|
Rows: 1 |
|
It is also possible to check whether a value is the only null value using the null type.
RETURN NULL IS :: NULL AS isNull
| isNull |
|---|
|
Rows: 1 |
Closed dynamic union types (INNER_TYPE_1 | INNER_TYPE_2…) cannot be declared as NOT NULL. Instead, all the inner types should be individually declared as not nullable to achieve this behavior.
Note that all inner types in a closed dynamic union must be either nullable, or not nullable. This is because null values cannot be attributed to a specific type. A syntax error will be raised if the inner types are not of the same nullability.
RETURN 1 IS :: INTEGER NOT NULL | FLOAT
All types in a Closed Dynamic Union must be nullable, or be appended with `NOT NULL`.
Type predicate expression for properties
Type predicate expressions can also be used to filter out nodes or relationships with properties of a certain type.
A graph containing the following nodes is used for the example below:
The following query finds all Person nodes with an age property that is an INTEGER with a value greater than 18.
MATCH (n:Person)
WHERE n.age IS :: INTEGER AND n.age > 18
RETURN n.name AS name, n.age AS age
| name | age |
|---|---|
|
|
Rows: 1 |
|
The type PROPERTY VALUE can also be used to check whether a type is storable as a property.
Types not storable in properties, such as MAP, will return false when checked with IS :: PROPERTY VALUE.
Type predicate expressions for numbers of different sizes
For numerical values passed in as parameters, Cypher does not take the size of the number into account.
Cypher will therefore regard any exact numerical parameter as an INTEGER regardless of its declared size.
For example, an INT16 or an INT32 passed through from a language library will both be treated by Cypher as an INTEGER.
Note that any exact numerical parameter used must fit within the range of an INT64.
RETURN $int16param IS :: INTEGER AS isInteger
| isInteger |
|---|
|
Rows: 1 |
More information about parameters can be found here.
Syntactical variations of type predicate expressions
Type predicate expressions allow for some alternative syntax:
<expr> IS TYPED <TYPE>
<expr> :: <TYPE>
For verifying that an expression is not of a certain type, the following alternative syntax is supported:
<expr> IS NOT TYPED <TYPE>
Use of ANY and NOTHING typesIntroduced in 5.10
ANY is a supertype which matches values of all types.
NOTHING is a type containing an empty set of values.
This means that it returns false for all values.
RETURN 42 IS :: ANY AS isOfTypeAny, 42 IS :: NOTHING AS isOfTypeNothing
| isOfTypeAny | isOfTypeNothing |
|---|---|
|
|
Rows: 1 |
|
Closed Dynamic UnionsIntroduced in 5.11
Closed dynamic union types allow for the testing of multiple types in the same predicate.
UNWIND [42, 42.0, "42"] as val
RETURN val, val IS :: INTEGER | FLOAT AS isNumber
| val | isNumber |
|---|---|
|
|
|
|
|
|
Rows: 3 |
|
List TypesIntroduced in 5.10
Type predicate expressions can be used for LIST types, where the inner type of the elements in the list must be specified.
If the inner type is not relevant, then the ANY type may be used.
For a LIST type check to return true, all values in the list must match the inner type.
UNWIND [[42], [42, null], [42, 42.0]] as val
RETURN val, val IS :: LIST<INTEGER> AS isIntList
| val | isIntList |
|---|---|
|
|
|
|
|
|
Rows: 3 |
|
An empty list will match on all inner types, even the NOTHING type.
RETURN
[] IS :: LIST<NOTHING> AS isNothingList,
[] IS :: LIST<INTEGER> AS isIntList,
[] IS :: LIST<FLOAT NOT NULL> AS isFloatNotNullList
| isNothingList | isIntList | isFloatNotNullList |
|---|---|---|
|
|
|
Rows: 1 |
||
Lists can be combined with closed dynamic union types to create tests for heterogeneous lists.
WITH [1, 0, true, false] AS booleanList
RETURN booleanList IS :: LIST<BOOLEAN | INTEGER> as isMixedList
| isMixedList |
|---|
|
Rows: 1 |