Values and types
Property types
A property type value is one that can be stored as a node or relationship property.
Property types are the most primitive types in Cypher and include the following:
BOOLEANDATEDURATIONFLOATINTEGERLISTLOCAL DATETIMELOCAL TIMEPOINTSTRINGZONED DATETIMEZONED TIME
Structural types
The following data types are included in the structural types category:
NODERELATIONSHIPPATH
Constructed types
The following data types are included in the constructed types category:
LISTMAP
Types and their synonyms
| Type | Synonyms |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All Cypher types contain the null value. To make them not nullable, NOT NULL can be appended to the end of the type (e.g. BOOLEAN NOT NULL, LIST<FLOAT NOT NULL>). A shorthand syntax equivalent, introduced in Neo4j 5.14, for NOT NULL is to use an exclamation mark ! (e.g. INTEGER!, LIST<STRING!>). Note that closed dynamic types (INNER_TYPE_1 | INNER_TYPE_2…) cannot be appended with NOT NULL: all inner types must be nullable, or all appended with NOT NULL.
Type Normalization
Cypher runs a normalization algorithm on all input types, simplifying the given type to a deterministic representation for equivalent types. Types are simplified to their default name (e.g. BOOL is simplified to BOOLEAN). Encompassing types are absorbed (e.g. LIST<BOOLEAN> | LIST<BOOLEAN | INTEGER> is normalized to LIST<BOOLEAN | INTEGER>). Types are also ordered.
The type PROPERTY VALUE is expanded to a closed dynamic union of all valid property types, and if all types are represented, then the normalization would simplify to ANY.
For example, given the closed dynamic type BOOL | LIST<INT> | BOOLEAN | LIST<FLOAT | INT>, the normalized type would be: BOOLEAN | LIST<INTEGER | FLOAT>.
This normalization is run on types used in type predicate expressions, and in property type constraints. Type normalization is also used to ensure the consistency of the output for the valueType() function.
Ordering of types
The ordering of types is as follows:
-
Predefined types
-
NOTHING -
NULL -
BOOLEAN -
STRING -
INTEGER -
FLOAT -
DATE -
LOCAL TIME -
ZONED TIME -
LOCAL DATETIME -
ZONED DATETIME -
DURATION -
POINT -
NODE -
RELATIONSHIP
-
-
Constructed types
-
MAP -
LIST<INNER_TYPE>(ordered by the inner type) -
PATH
-
-
Dynamic union types
-
INNER_TYPE_1 \| INNER_TYPE_2…(ordered by specific rules for closed dynamic union type) -
ANY
-
Subtypes are always ordered before any enclosing types (e.g. LIST<INTEGER> is ordered before LIST<INTEGER | FLOAT>). This also means that the NOT NULL variants of each type comes before the nullable variant.
The order between two closed dynamic unions A and B is determined as followed:
-
If
Ahas fewer inner types thanB,Ais ordered first. -
If
AandBhave the same number of inner types, they are ordered according to the order of the first inner type that differ (lexicographic order).
The resulting order is deterministic.
Property type details
The below table provides more detailed information about the various property types that Cypher supports. Note that Cypher types are implemented using Java, and that below table references Java value constants.
| Type | Min. value | Max. value | Precision |
|---|---|---|---|
|
|
|
|
- |
|
|
|
|
Days |
|
|
|
|
Nanoseconds |
|
|
|
|
64 bit |
|
|
|
|
64 bit |
|
|
|
|
Nanoseconds |
|
|
|
|
Nanoseconds |
|
|
Cartesian: ( Cartesian_3D: ( WGS_84: ( WGS_84_3D: ( |
Cartesian: ( Cartesian_3D: ( WGS_84: ( WGS_84_3D: ( |
The precision of each coordinate of the |
|
|
- |
- |
- |
|
|
|
|
Nanoseconds |
|
|
|
|
Nanoseconds |
Java value details
| Name | Value |
|---|---|
|
|
1.7976931348623157e+308 |
|
|
4.9e-324 |
|
|
2^63-1 |
|
|
-2^63 |
Temporal values
DATE, LOCAL TIME, ZONED TIME, LOCAL DATETIME, and ZONED DATETIME are temporal instant types. A temporal instant value expresses a point in time with varying degrees of precision.
By contrast, DURATION is not a temporal instant type. A DURATION represents a temporal amount, capturing the difference in time between two instants, and can be negative. DURATION captures the amount of time between two instants, it does not capture a start time and end time.
Starting from Neo4j 5.9, some temporal types have been renamed. The table below shows the current as well as the old names of the temporal types.
| Type | Old type name |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Spatial values
The POINT type
Neo4j supports the POINT type for values of spatial geometry.
Values with the POINT type have the following characteristics:
-
Each point can have either 2 or 3 dimensions. This means it contains either 2 or 3 64-bit
FLOATvalues, which together are called the Coordinate. -
Each point will also be associated with a specific Coordinate Reference System (CRS) that determines the meaning of the values in the Coordinate.
-
Instances of
POINTandLIST<POINT>can be assigned to node and relationship properties. -
Nodes and relationships with
POINTorLIST<POINT>properties can be indexed using a point index. This is true for all CRSs (and for both 2D and 3D). -
The distance function will work on points in all CRS and in both 2D and 3D, but only if the two points have the same CRS (and therefore also same dimension).
Coordinate Reference Systems
Four Coordinate Reference Systems (CRS) are supported, each of which falls within one of two types: geographic coordinates, modeling points on the earth, or Cartesian coordinates, modeling points in euclidean space:
Data within different coordinate systems are entirely incomparable, and cannot be implicitly converted from one to the other. This is true even if they are both Cartesian or both geographic but of a different dimension. For example, if you search for 3D points using a 2D range, you will get no results. However, they can be ordered, as discussed in more detail in the section about ordering and comparison of values.
Geographic coordinate reference systems
Two Geographic Coordinate Reference Systems (CRS) are supported, modeling points on the earth:
-
-
A 2D geographic point in the WGS 84 CRS is specified in one of two ways:
-
longitudeandlatitude(if these are specified, and thecrsis not, then thecrsis assumed to beWGS-84). -
xandy(in this case thecrsmust be specified, or will be assumed to be Cartesian).
-
-
Specifying this CRS can be done using either the name 'wgs-84' or the SRID 4326 as described in point() - WGS 84 2D.
-
-
-
A 3D geographic point in the WGS 84 CRS is specified one of in two ways:
-
longitude,latitudeand eitherheightorz(if these are specified, and thecrsis not, then thecrsis assumed to beWGS-84-3D). -
x,yandz(in this case thecrsmust be specified, or will be assumed to be Cartesian-3D).
-
-
Specifying this CRS can be done using either the name 'wgs-84-3d' or the SRID 4979 as described in point() - WGS 84 3D.
-
Converting coordinate units
The units of the latitude and longitude fields are in decimal degrees, and need to be specified as floating point numbers using Cypher literals. It is not possible to use any other format, such as 'degrees, minutes, seconds'. The units of the height field are in meters. When geographic points are passed to the distance function, the result will always be in meters. If the coordinates are in any other format or unit than those supported, it is necessary to explicitly convert them.
For example, if the incoming $height is a STRING field in kilometers, it would be necessary to add height: toFloat($height) * 1000 to the query. Likewise if the results of the distance function are expected to be returned in kilometers, an explicit conversion is required. The below query is an example of this conversion:
WITH
point({latitude: toFloat('13.43'), longitude: toFloat('56.21')}) AS p1,
point({latitude: toFloat('13.10'), longitude: toFloat('56.41')}) AS p2
RETURN toInteger(point.distance(p1, p2)/1000) AS km
Cartesian coordinate reference systems
Two Cartesian Coordinate Reference Systems (CRS) are supported, modeling points in euclidean space:
-
Cartesian 2D
-
A 2D point in the Cartesian CRS is specified with a map containing
xandycoordinate values -
Specifying this CRS can be done using either the name 'cartesian' or the SRID 7203 as described in point() - Cartesian 2D
-
-
Cartesian 3D
-
A 3D point in the Cartesian CRS is specified with a map containing
x,yandzcoordinate values -
Specifying this CRS can be done using either the name 'cartesian-3d' or the SRID 9157 as described in point() - Cartesian 3D)
-
The units of the x, y, and z fields are unspecified. This means that when two Cartesian points are passed to the distance function, the resulting value will be in the same units as the original coordinates. This is true for both 2D and 3D points, as the Pythagoras equation used is generalized to any number of dimensions. However, just as you cannot compare geographic points to Cartesian points, you cannot calculate the distance between a 2D point and a 3D point. If you need to do that, explicitly transform the one type into the other. For example:
WITH
point({x: 3, y: 0}) AS p2d,
point({x: 0, y: 4, z: 1}) AS p3d
RETURN
point.distance(p2d, p3d) AS bad,
point.distance(p2d, point({x: p3d.x, y: p3d.y})) AS good
Spatial instants
All POINT types are created from two components:
-
The Coordinate containing either 2 or 3
FLOATvalues (64-bit). -
The Coordinate Reference System (or CRS) defining the meaning (and possibly units) of the values in the Coordinate.
For most use cases, it is not necessary to specify the CRS explicitly as it will be deduced from the keys used to specify the coordinate. Two rules are applied to deduce the CRS from the coordinate:
-
Choice of keys:
-
If the coordinate is specified using the keys
latitudeandlongitudethe CRS will be assumed to be Geographic and therefor eitherWGS-84orWGS-84-3D. -
If instead
xandyare used, then the default CRS would beCartesianorCartesian-3D.
-
-
Number of dimensions:
-
If there are 2 dimensions in the coordinate,
x&yorlongitude&latitudethe CRS will be a 2D CRS. -
If there is a third dimensions in the coordinate,
zorheightthe CRS will be a 3D CRS.
-
All fields are provided to the point function in the form of a map of explicitly named arguments. Neo4j does not support an ordered list of coordinate fields because of the contradictory conventions between geographic and cartesian coordinates, where geographic coordinates normally list y before x (latitude before longitude).
The following query which returns points created in each of the four supported CRSs. Take particular note of the order and keys of the coordinates in the original point function, and how those values are displayed in the results:
RETURN
point({x: 3, y: 0}) AS cartesian_2d,
point({x: 0, y: 4, z: 1}) AS cartesian_3d,
point({latitude: 12, longitude: 56}) AS geo_2d,
point({latitude: 12, longitude: 56, height: 1000}) AS geo_3d
╒════════════════════════════╤═════════════════════════════════╤══════════════════════════════╤══════════════════════════════════════╕
│cartesian_2d │cartesian_3d │geo_2d │geo_3d │
╞════════════════════════════╪═════════════════════════════════╪══════════════════════════════╪══════════════════════════════════════╡
│point({srid:7203, x:3, y:0})│point({srid:9157, x:0, y:4, z:1})│point({srid:4326, x:56, y:12})│point({srid:4979, x:56, y:12, z:1000})│
└────────────────────────────┴─────────────────────────────────┴──────────────────────────────┴──────────────────────────────────────┘
For the geographic coordinates, it is important to note that the latitude value should always lie in the interval [-90, 90]. Any other value outside this range will throw an exception. The longitude value should always lie in the interval [-180, 180]. Any other value outside this range will be wrapped around to fit in this range. The height value and any Cartesian coordinates are not explicitly restricted. Any value within the allowed range of the signed 64-bit floating point type will be accepted.
Components of points
Components of POINT values can be accessed as properties.
| Component |
|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Spatial values and indexes
If there is a range or point index on a particular node or relationship property, and a spatial point is assigned to that property on a node or relationship, the node or relationship will be indexed.
In a point index, Neo4j uses space filling curves in 2D or 3D over an underlying generalized B+Tree. Point indexes are optimized for distance and bounding box queries. For more information, see Managing indexes → Point indexes.
In a range index, the points will be sorted according to their lexicographic ordering per coordinate reference system. For point values, this index has support for equality checks. For more information, see Managing indexes → Range indexes.
Comparability and orderability
Cypher does not support comparing spatial values using the inequality operators, <, <=, >, and >=. Attempting to do so will return null.
To compare spatial points within a specific range, instead use the spatial functions point.distance or point.withinBBox.
Working with null
In Cypher®, null is used to represent missing or undefined values. All data types in Cypher are nullable. This means that type predicate expressions always return true for null values.
Conceptually, null means a missing or unknown value, and it is treated somewhat differently from other values. For example, returning a property from a node that does not have said property produces null. Most expressions that take null as input will produce null. In the case of a predicate used in a WHERE clause, anything that is not true is interpreted as being false.
null is not equal to null. Not knowing two values does not imply that they are the same value. This means that the expression null = null yields null, and not true.
Logical operations with null
The logical operators (AND, OR, XOR, NOT) treat null as the unknown value of three-valued logic.
| a | b | a AND b | a OR b | a XOR b | NOT a |
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The IN operator and null
The IN operator follows similar logic. If Cypher can ascertain that something exists in a list, the result will be true. Any list that contains a null and does not have a matching element will return null. Otherwise, the result will be false.
| Expression | Result |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Using all, any, none, and single follows a similar rule. If the result can be calculated definitively, true or false is returned. Otherwise null is produced.
The [] operator and null
Accessing a list or a map with null will result in null:
| Expression | Result |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Using parameters to pass in the bounds, such as a[$lower..$upper], may result in a null for the lower or upper bound (or both). The following workaround will prevent this from happening by setting the absolute minimum and maximum bound values:
a[coalesce($lower,0)..coalesce($upper,size(a))]
Expressions that return null
-
Getting a missing element from a list:
[][0],head([]). -
Trying to access a property that does not exist on a node or relationship:
n.missingProperty. -
Comparisons when either side is
null:1 < null. -
Arithmetic expressions containing
null:1 + null. -
Some function calls where any argument is
null: e.g.,sin(null).
Using IS NULL and IS NOT NULL
Testing any value against null, either with the = operator or with the <> operator, always evaluates to null. Therefore, use the special equality operators IS NULL or IS NOT NULL.
Lists
Cypher® includes comprehensive support for lists.
List range and size
The below examples use the range function to create lists. This function returns a list containing all numbers between given start and end numbers. The range is inclusive in both ends.
RETURN range(0, 10) AS list
╒══════════════════════════════════╕ │list │ ╞══════════════════════════════════╡ │[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]│ └──────────────────────────────────┘
It is possible to use negative numbers, to start from the end of the list instead.
RETURN range(0, 10)[3] AS element1, range(0, 10)[-3] AS element2
╒════════╤════════╕ │element1│element2│ ╞════════╪════════╡ │3 │8 │ └────────┴────────┘
Finally, it is possible to use ranges inside the brackets to return ranges of the list. The list range operator ([]) is inclusive of the first value, but exclusive of the last value.
RETURN range(0, 10)[0..3] AS list
╒═════════╕ │list │ ╞═════════╡ │[0, 1, 2]│ └─────────┘
Pattern comprehension
Pattern comprehension is a syntactic construct available in Cypher for creating a list based on matchings of a pattern. A pattern comprehension matches the specified pattern like a normal MATCH clause, with predicates like a normal WHERE clause, but yields a custom projection as specified.

CREATE
(keanu:Person {name: 'Keanu Reeves'}),
(johnnyMnemonic:Movie {title: 'Johnny Mnemonic', released: 1995}),
(theMatrixRevolutions:Movie {title: 'The Matrix Revolutions', released: 2003}),
(theMatrixReloaded:Movie {title: 'The Matrix Reloaded', released: 2003}),
(theReplacements:Movie {title: 'The Replacements', released: 2000}),
(theMatrix:Movie {title: 'The Matrix', released: 1999}),
(theDevilsAdvocate:Movie {title: 'The Devils Advocate', released: 1997}),
(theMatrixResurrections:Movie {title: 'The Matrix Resurrections', released: 2021}),
(keanu)-[:ACTED_IN]->(johnnyMnemonic),
(keanu)-[:ACTED_IN]->(theMatrixRevolutions),
(keanu)-[:ACTED_IN]->(theMatrixReloaded),
(keanu)-[:ACTED_IN]->(theReplacements),
(keanu)-[:ACTED_IN]->(theMatrix),
(keanu)-[:ACTED_IN]->(theDevilsAdvocate),
(keanu)-[:ACTED_IN]->(theMatrixResurrections)
Examples
This example returns a list that contains the year when the movies were released. The pattern matching in the pattern comprehension looks for Matrix in the movie title and that the node keanu (Person node with the name Keanu Reeves) has a relationship with the movie.
MATCH (keanu:Person {name: 'Keanu Reeves'})
RETURN [(keanu)-->(b:Movie) WHERE b.title CONTAINS 'Matrix' | b.released] AS years
╒════════════════════════╕ │years │ ╞════════════════════════╡ │[2003, 2003, 1999, 2021]│ └────────────────────────┘
List comprehension
List comprehension is a syntactic construct available in Cypher for creating a list based on existing lists.
List comprehension follows the form of the mathematical set-builder notation (set comprehension) instead of the use of map and filter functions.
RETURN [x IN range(0,10) WHERE x % 2 = 0 | x^3 ] AS result
╒══════════════════════════════════════╕ │result │ ╞══════════════════════════════════════╡ │[0.0, 8.0, 64.0, 216.0, 512.0, 1000.0]│ └──────────────────────────────────────┘
Either the WHERE part, or the expression, can be omitted, if you only want to filter or map respectively.
RETURN [x IN range(0,10) WHERE x % 2 = 0 ] AS result
╒═══════════════════╕ │result │ ╞═══════════════════╡ │[0, 2, 4, 6, 8, 10]│ └───────────────────┘
RETURN [x IN range(0,10) | x^3 ] AS result
╒══════════════════════════════════════════════════════════════════════╕ │result │ ╞══════════════════════════════════════════════════════════════════════╡ │[0.0, 1.0, 8.0, 27.0, 64.0, 125.0, 216.0, 343.0, 512.0, 729.0, 1000.0]│ └──────────────────────────────────────────────────────────────────────┘
Maps
Literal maps
RETURN {key: 'Value', listKey: [{inner: 'Map1'}, {inner: 'Map2'}]} AS map
Map projection
Cypher supports map projections, which allows for the construction of map projections from nodes, relationships, and other map values.
A map projection begins with the variable bound to the graph entity to be projected from, and contains a body of comma-separated map elements, enclosed by { and }.
map_variable {map_element, [, ...n]}
A map element projects one or more key-value pairs to the map projection. There exist four different types of map projection elements:
-
Property selector - Projects the property name as the key, and the value from the
map_variableas the value for the projection. -
Literal entry - This is a key-value pair, with the value being an arbitrary expression
key: <expression>. -
Variable selector - Projects a variable, with the variable name as the key, and the value the variable is pointing to as the value of the projection. Its syntax is just the variable.
-
All-properties selector - projects all key-value pairs from the
map_variablevalue.
The following conditions apply:
-
If the
map_variablepoints to anullvalue, the whole map projection will evaluate tonull. -
The key names in a map must be of type
STRING.

CREATE
(keanu:Person {name: 'Keanu Reeves', nationality: 'Canadian'}),
(carrieAnne:Person {name: 'Carrie-Anne Moss'}),
(theMatrixRevolutions:Movie {title: 'The Matrix Revolutions', released: 2003}),
(theMatrixReloaded:Movie {title: 'The Matrix Reloaded', released: 2003}),
(theMatrix:Movie {title: 'The Matrix', released: 1999}),
(theDevilsAdvocate:Movie {title: 'The Devils Advocate', released: 1997}),
(theMatrixResurrections:Movie {title: 'The Matrix Resurrections', released: 2021}),
(keanu)-[:ACTED_IN]->(theMatrix),
(keanu)-[:ACTED_IN]->(theMatrixRevolutions),
(keanu)-[:ACTED_IN]->(theMatrixReloaded),
(keanu)-[:ACTED_IN]->(theMatrixResurrections),
(keanu)-[:ACTED_IN]->(theDevilsAdvocate),
(carrieAnne)-[:ACTED_IN]->(theMatrix),
(carrieAnne)-[:ACTED_IN]->(theMatrixRevolutions),
(carrieAnne)-[:ACTED_IN]->(theMatrixReloaded),
(carrieAnne)-[:ACTED_IN]->(theMatrixResurrections)
Examples
The below query finds the Keanu Reeves node and the movies he has acted in. It is an example of a map projection with a literal entry, which in turn also uses map projection with a property selector inside the aggregating collect() function.
MATCH (keanu:Person {name: 'Keanu Reeves'})-[:ACTED_IN]->(movie:Movie)
WITH keanu, collect(movie{.title, .released}) AS movies
RETURN keanu{.name, movies: movies}
╒══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╕
│keanu │
╞══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
│{name: "Keanu Reeves", movies: [{released: 2003, title: "The Matrix Revolutions"}, {released: 2003, title: "The Matrix Reloaded"}, {released: │
│1999, title: "The Matrix"}, {released: 1997, title: "The Devils Advocate"}, {released: 2021, title: "The Matrix Resurrections"}]} │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
The below query finds all Person nodes in the graph that have one or more relationships with the type ACTED_IN connected to Movie nodes. It uses the count() function to count how many Movie nodes are connected to each Person node in this way, and uses a variable selector to project the value of the count.
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie) WITH actor, count(movie) AS numberOfMovies RETURN actor{.name, numberOfMovies}
╒═════════════════════════════════════════════╕
│actor │
╞═════════════════════════════════════════════╡
│{name: "Keanu Reeves", numberOfMovies: 5} │
├─────────────────────────────────────────────┤
│{name: "Carrie-Anne Moss", numberOfMovies: 4}│
└─────────────────────────────────────────────┘
The below query returns all properties from the Keanu Reeves node. An all-properties selector is used to project all the node properties, and additionally, explicitly project the property age. Since this property does not exist on the node Keanu Reeves, a null value is projected instead.
MATCH (keanu:Person {name: 'Keanu Reeves'})
RETURN keanu{.*, .age}
╒══════════════════════════════════════════════════════════╕
│keanu │
╞══════════════════════════════════════════════════════════╡
│{nationality: "Canadian", age: null, name: "Keanu Reeves"}│
└──────────────────────────────────────────────────────────┘
The below query is an example of statically accessing individual map members using the . operator:
WITH {age: 58, profession: 'Actor'} as keanuStats
RETURN keanuStats.profession AS profession
Casting data values
Cypher® supports a number of functions to cast values to different data types.
Functions for converting data values
| Function | Description |
|---|---|
|
|
Converts a |
|
|
Converts a |
|
|
Converts a |
|
|
Converts an |
|
|
Converts a |
|
|
Converts an |
|
|
Converts a |
|
|
Converts a |
|
|
Converts a |
|
|
Converts an |
|
|
Converts a |
|
|
Converts an |
WITH date({
year: 2023, month: 5, day: 2
}) AS d
RETURN toFloat(d)

However, if the same value is passed to the function toFloatOrNull, null will be returned.
WITH date({
year: 2023, month: 5, day: 2
}) AS d
RETURN toFloatOrNull(d)
╒════════════════╕ │toFloatOrNull(d)│ ╞════════════════╡ │null │ └────────────────┘
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>
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 │ └─────┴─────────┘
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 │ └─────┴─────────┘
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 │ └─────────┴────────────────┘
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 │ └─────────┴────────────────┘
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 │ └──────┘
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

RETURN 1 IS :: INTEGER | FLOAT
╒═══════════════════════╕ │1 IS :: INTEGER | FLOAT│ ╞═══════════════════════╡ │true │ └───────────────────────┘
RETURN 1 IS :: INTEGER NOT NULL | FLOAT NOT NULL
╒═════════════════════════════════════════╕ │1 IS :: INTEGER NOT NULL | FLOAT NOT NULL│ ╞═════════════════════════════════════════╡ │true │ └─────────────────────────────────────────┘
Type predicate expression for properties
Type predicate expressions can also be used to filter out nodes or relationships with properties of a certain type.
MATCH (n:Person) WHERE n.age IS :: INTEGER AND n.age > 18 RETURN n.name AS name, n.age AS age
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.
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 │ └───────────┴───────────────┘
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 │ └────┴────────┘
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 │ └──────────┴─────────┘
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 │ └─────────────┴─────────┴──────────────────┘
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 │ └───────────┘

浙公网安备 33010602011771号