Type predicate expressions

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

42

true

true

false

'abc'

false

null

true

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

42

true

true

true

'abc'

false

null

false

Rows: 4

Type predicate expressions for null

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

true

false

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

false

true

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

true

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
Error message
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:

type predicate expression graph

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

'Charlie'

21

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

true

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 types

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

true

false

Rows: 1

Closed Dynamic Unions

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

42

true

42.0

true

"42"

false

Rows: 3

List Types

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

[42]

true

[42, null]

true

[42, 42.0]

false

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

true

true

true

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

true

Rows: 1