The Neo4j Cypher Manual V3.5 3.5

neo4j-cypher-manual-3.5

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 434

DownloadThe Neo4j Cypher Manual V3.5 Neo4j-cypher-manual-3.5
Open PDF In BrowserView PDF
The Neo4j Cypher Manual v3.5

Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Syntax. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3. Clauses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4. Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
5. Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
6. Query tuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
7. Execution plans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
8. Deprecations, additions and compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
9. Glossary of keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422

© 2018 Neo4j, Inc.
License: Creative Commons 4.0
This is the Cypher manual for Neo4j version 3.5, authored by the Neo4j Team.

This manual covers the following areas:
• Introduction — Introducing the Cypher query language.
• Syntax — Learn Cypher query syntax.
• Clauses — Reference of Cypher query clauses.
• Functions — Reference of Cypher query functions.
• Schema — Working with indexes and constraints in Cypher.
• Query tuning — Learn to analyze queries and tune them for performance.
• Execution plans — Cypher execution plans and operators.
• Deprecations, additions and compatibility — An overview of language
developments across versions.
• Glossary of keywords — A glossary of Cypher keywords, with links to other
parts of the Cypher manual.
Who should read this?
This manual is written for the developer of a Neo4j client application.

1

Chapter 1. Introduction
This section provides an introduction to the Cypher query language.

1.1. What is Cypher?
Cypher is a declarative graph query language that allows for expressive and efficient querying and
updating of the graph. It is designed to be suitable for both developers and operations professionals.
Cypher is designed to be simple, yet powerful; highly complicated database queries can be easily
expressed, enabling you to focus on your domain, instead of getting lost in database access.
Cypher is inspired by a number of different approaches and builds on established practices for
expressive querying. Many of the keywords, such as WHERE and ORDER BY, are inspired by SQL
(http://en.wikipedia.org/wiki/SQL). Pattern matching borrows expression approaches from SPARQL
(http://en.wikipedia.org/wiki/SPARQL). Some of the list semantics are borrowed from languages such as
Haskell and Python. Cypher’s constructs, based on English prose and neat iconography, make queries
easy both to write, and to read.
Structure
Cypher borrows its structure from SQL — queries are built up using various clauses.
Clauses are chained together, and they feed intermediate result sets between each other. For
example, the matching variables from one MATCH clause will be the context that the next clause exists
in.
The query language is comprised of several distinct clauses. You can read more details about them
later in the manual.
Here are a few clauses used to read from the graph:
• MATCH: The graph pattern to match. This is the most common way to get data from the graph.
• WHERE: Not a clause in its own right, but rather part of MATCH, OPTIONAL MATCH and WITH. Adds
constraints to a pattern, or filters the intermediate result passing through WITH.
• RETURN: What to return.
Let’s see MATCH and RETURN in action.
Imagine an example graph like the following one:

name = 'John'

friend

name = 'Joe'

friend

name = 'Sara'

friend

name = 'Steve'

friend

name = 'Maria'

Figure 1. Example Graph
For example, here is a query which finds a user called 'John' and 'John’s' friends (though not his direct

2

friends) before returning both 'John' and any friends-of-friends that are found.
MATCH (john {name: 'John'})-[:friend]->()-[:friend]->(fof)
RETURN john.name, fof.name

Resulting in:
+----------------------+
| john.name | fof.name |
+----------------------+
| "John"
| "Maria" |
| "John"
| "Steve" |
+----------------------+
2 rows

Next up we will add filtering to set more parts in motion:
We take a list of user names and find all nodes with names from this list, match their friends and
return only those followed users who have a 'name' property starting with 'S'.
MATCH (user)-[:friend]->(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*'
RETURN user.name, follower.name

Resulting in:
+---------------------------+
| user.name | follower.name |
+---------------------------+
| "Joe"
| "Steve"
|
| "John"
| "Sara"
|
+---------------------------+
2 rows

And here are examples of clauses that are used to update the graph:
• CREATE (and DELETE): Create (and delete) nodes and relationships.
• SET (and REMOVE): Set values to properties and add labels on nodes using SET and use REMOVE to
remove them.
• MERGE: Match existing or create new nodes and patterns. This is especially useful together with
unique constraints.

1.2. Querying and updating the graph
Cypher can be used for both querying and updating your graph.

1.2.1. The structure of update queries
A Cypher query part can’t both match and update the graph at the same time.
Every part can either read and match on the graph, or make updates on it.
If you read from the graph and then update the graph, your query implicitly has two parts — the
reading is the first part, and the writing is the second part.
If your query only performs reads, Cypher will be lazy and not actually match the pattern until you ask
for the results. In an updating query, the semantics are that all the reading will be done before any

3

writing actually happens.
The only pattern where the query parts are implicit is when you first read and then write — any other
order and you have to be explicit about your query parts. The parts are separated using the WITH
statement. WITH is like an event horizon — it’s a barrier between a plan and the finished execution of
that plan.
When you want to filter using aggregated data, you have to chain together two reading query
parts — the first one does the aggregating, and the second filters on the results coming from the first
one.
MATCH (n {name: 'John'})-[:FRIEND]-(friend)
WITH n, count(friend) AS friendsCount
WHERE friendsCount > 3
RETURN n, friendsCount

Using WITH, you specify how you want the aggregation to happen, and that the aggregation has to be
finished before Cypher can start filtering.
Here’s an example of updating the graph, writing the aggregated data to the graph:
MATCH (n {name: 'John'})-[:FRIEND]-(friend)
WITH n, count(friend) AS friendsCount
SET n.friendsCount = friendsCount
RETURN n.friendsCount

You can chain together as many query parts as the available memory permits.

1.2.2. Returning data
Any query can return data. If your query only reads, it has to return data — it serves no purpose if it
doesn’t, and it is not a valid Cypher query. Queries that update the graph don’t have to return
anything, but they can.
After all the parts of the query comes one final RETURN clause. RETURN is not part of any query part — it
is a period symbol at the end of a query. The RETURN clause has three sub-clauses that come with it:
SKIP/LIMIT and ORDER BY.
If you return nodes or relationships from a query that has just deleted them — beware, you are
holding a pointer that is no longer valid.

1.3. Transactions
Any query that updates the graph will run in a transaction. An updating query will always either fully
succeed, or not succeed at all.
Cypher will either create a new transaction or run inside an existing one:
• If no transaction exists in the running context Cypher will create one and commit it once the query
finishes.
• In case there already exists a transaction in the running context, the query will run inside it, and
nothing will be persisted to disk until that transaction is successfully committed.
This can be used to have multiple queries be committed as a single transaction:
1. Open a transaction,
2. Run multiple updating Cypher queries.

4

3. Commit all of them in one go.
Note that a query will hold the changes in memory until the whole query has finished executing. A
large query will consequently use large amounts of memory. For memory configuration in Neo4j, see
the Neo4j Operations Manual.
For using transactions with a Neo4j driver, see the Neo4j Driver manual. For using transactions over
the HTTP API, see the HTTP API documentation.
When writing procedures or using Neo4j embedded, remember that all iterators returned from an
execution result should be either fully exhausted or closed. This ensures that the resources bound to
them are properly released.

1.4. Uniqueness
While pattern matching, Neo4j makes sure to not include matches where the same graph relationship
is found multiple times in a single pattern. In most use cases, this is a sensible thing to do.
Example: looking for a user’s friends of friends should not return said user.
Let’s create a few nodes and relationships:
CREATE (adam:User { name: 'Adam' }),(pernilla:User { name: 'Pernilla' }),(david:User { name: 'David'
}),
(adam)-[:FRIEND]->(pernilla),(pernilla)-[:FRIEND]->(david)

Which gives us the following graph:
User
name = 'Adam'

FRIEND

User
name = 'Pernilla'

FRIEND

User
name = 'David'

Now let’s look for friends of friends of Adam:
MATCH (user:User { name: 'Adam' })-[r1:FRIEND]-()-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName

+---------+
| fofName |
+---------+
| "David" |
+---------+
1 row

In this query, Cypher makes sure to not return matches where the pattern relationships r1 and r2
point to the same graph relationship.
This is however not always desired. If the query should return the user, it is possible to spread the

5

matching over multiple MATCH clauses, like so:
MATCH (user:User { name: 'Adam' })-[r1:FRIEND]-(friend)
MATCH (friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName

+---------+
| fofName |
+---------+
| "David" |
| "Adam" |
+---------+
2 rows

Note that while the following query looks similar to the previous one, it is actually equivalent to the
one before.
MATCH (user:User { name: 'Adam' })-[r1:FRIEND]-(friend),(friend)-[r2:FRIEND]-(friend_of_a_friend)
RETURN friend_of_a_friend.name AS fofName

Here, the MATCH clause has a single pattern with two paths, while the previous query has two distinct
patterns.
+---------+
| fofName |
+---------+
| "David" |
+---------+
1 row

6

Chapter 2. Syntax
This section describes the syntax of the Cypher query language.
• Values and types
• Naming rules and recommendations
• Expressions
• Expressions in general
• Note on string literals
• CASE Expressions
• Variables
• Reserved keywords
• Parameters
• String literal
• Regular expression
• Case-sensitive string pattern matching
• Create node with properties
• Create multiple nodes with properties
• Setting all properties on a node
• SKIP and LIMIT
• Node id
• Multiple node ids
• Calling procedures
• Index value (explicit indexes)
• Index query (explicit indexes)
• Operators
• Operators at a glance
• Aggregation operators
• Mathematical operators
• Comparison operators
• Boolean operators
• String operators
• Temporal operators
• List operators
• Property operators
• Equality and comparison of values
• Ordering and comparison of values
• Chaining comparison operations
• Comments

7

• Patterns
• Patterns for nodes
• Patterns for related nodes
• Patterns for labels
• Specifying properties
• Patterns for relationships
• Variable-length pattern matching
• Assigning to path variables
• Temporal (Date/Time) values
• Introduction
• Time zones
• Temporal instants
• Specifying temporal instants
• Specifying dates
• Specifying times
• Specifying time zones
• Examples
• Accessing components of temporal instants
• Durations
• Specifying durations
• Examples
• Accessing components of durations
• Examples
• Temporal indexing
• Spatial values
• Introduction
• Coordinate Reference Systems
• Geographic coordinate reference systems
• Cartesian coordinate reference systems
• Spatial instants
• Creating points
• Accessing components of points
• Spatial index
• Lists
• Lists in general
• List comprehension
• Pattern comprehension

8

• Maps
• Literal maps
• Map projection
• Working with null
• Introduction to null in Cypher
• Logical operations with null
• The [] operator and null
• The IN operator and null
• Expressions that return null

2.1. Values and types
Cypher provides first class support for a number of data types.
These fall into several categories which will be described in detail in the following subsections:
• Property types
• Structural types
• Composite types

2.1.1. Property types
☑ Can be returned from Cypher queries
☑ Can be used as parameters
☑ Can be stored as properties
☑ Can be constructed with Cypher literals
Property types comprise:
• Number, an abstract type, which has the subtypes Integer and Float
• String
• Boolean
• The spatial type Point
• Temporal types: Date, Time, LocalTime, DateTime, LocalDateTime and Duration
The adjective numeric, when used in the context of describing Cypher functions or expressions,
indicates that any type of Number applies (Integer or Float).
Homogeneous lists of simple types can also be stored as properties, although lists in general (see
Composite types) cannot be stored.
Cypher also provides pass-through support for byte arrays, which can be stored as property values.
Byte arrays are not considered a first class data type by Cypher, so do not have a literal
representation.

9

Sorting of special characters
Strings that contain characters that do not belong to the Basic Multilingual Plane
(https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane) (BMP) can have
inconsistent or non-deterministic ordering in Neo4j. BMP is a subset of all
characters defined in Unicode. Expressed simply, it contains all common characters
from all common languages.
The most significant characters not in BMP are those belonging to the
Supplementary Multilingual Plane



(https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane) or the

Supplementary Ideographic Plane
(https://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Ideographic_Plane). Examples

are:
• Historic scripts and symbols and notation used within certain fields such as:
Egyptian hieroglyphs, modern musical notation, mathematical alphanumerics.
• Emojis and other pictographic sets.
• Game symbols for playing cards, Mah Jongg, and dominoes.
• CJK Ideograph that were not included in earlier character encoding standards.

2.1.2. Structural types
☑ Can be returned from Cypher queries
☐ Cannot be used as parameters
☐ Cannot be stored as properties
☐ Cannot be constructed with Cypher literals
Structural types comprise:
• Nodes, comprising:
• Id
• Label(s)
• Map (of properties)
• Relationships, comprising:
• Id
• Type
• Map (of properties)
• Id of the start and end nodes
• Paths
• An alternating sequence of nodes and relationships



Nodes, relationships, and paths are returned as a result of pattern matching.



Labels are not values but are a form of pattern syntax.

10

2.1.3. Composite types
☑ Can be returned from Cypher queries
☑ Can be used as parameters
☐ Cannot be stored as properties
☑ Can be constructed with Cypher literals
Composite types comprise:
• Lists are heterogeneous, ordered collections of values, each of which has any property, structural
or composite type.
• Maps are heterogeneous, unordered collections of (key, value) pairs, where:
• the key is a String
• the value has any property, structural or composite type



Composite values can also contain null.

Special care must be taken when using null (see Working with null).

2.2. Naming rules and recommendations
We describe here rules and recommendations for the naming of node labels, relationship types,
property names and variables.

2.2.1. Naming rules
• Must begin with an alphabetic letter.
• This includes "non-English" characters, such as å, ä, ö, ü etc.
• If a leading non-alphabetic character is required, use backticks for escaping; e.g. `^n`.
• Can contain numbers, but not as the first character.
• To illustrate, 1first is not allowed, whereas first1 is allowed.
• If a leading numeric character is required, use backticks for escaping; e.g. `1first`.
• Cannot contain symbols.
• An exception to this rule is using underscore, as given by my_variable.
• An ostensible exception to this rule is using $ as the first character to denote a parameter, as
given by $myParam.
• If a leading symbolic character is required, use backticks for escaping; e.g. `$$n`.
• Can be very long, up to 65535 (2^16 - 1) or 65534 characters, depending on the version of Neo4j.
• Are case-sensitive.
• Thus, :PERSON, :Person and :person are three different labels, and n and N are two different
variables.
• Whitespace characters:
• Leading and trailing whitespace characters will be removed automatically. For example, MATCH

11

(

a

) RETURN a is equivalent to MATCH (a) RETURN a.

• If spaces are required within a name, use backticks for escaping; e.g. `my variable has
spaces`.

2.2.2. Scoping and namespace rules
• Node labels, relationship types and property names may re-use names.
• The following query — with a for the label, type and property name — is valid: CREATE (a:a {a:
'a'})-[r:a]→(b:a {a: 'a'}).
• Variables for nodes and relationships must not re-use names within the same query scope.
• The following query is not valid as the node and relationship both have the name a: CREATE
(a)-[a]→(b).

2.2.3. Recommendations
Here are the naming conventions we recommend using:
Node labels

Camel case, beginning with an uppercase character

:VehicleOwner rather than
:vehice_owner etc.

Relationship types

Upper case, using underscore to
separate words

:OWNS_VEHICLE rather than
:ownsVehicle etc

2.3. Expressions
• Expressions in general
• Note on string literals
• CASE expressions
• Simple CASE form: comparing an expression against multiple values
• Generic CASE form: allowing for multiple conditionals to be expressed
• Distinguishing between when to use the simple and generic CASE forms

2.3.1. Expressions in general



Most expressions in Cypher evaluate to null if any of their inner expressions are
null. Notable exceptions are the operators IS NULL and IS NOT NULL.

An expression in Cypher can be:
• A decimal (integer or double) literal: 13, -40000, 3.14, 6.022E23.
• A hexadecimal integer literal (starting with 0x): 0x13zf, 0xFC3A9, -0x66eff.
• An octal integer literal (starting with 0): 01372, 02127, -05671.
• A string literal: 'Hello', "World".
• A boolean literal: true, false, TRUE, FALSE.
• A variable: n, x, rel, myFancyVariable, `A name with weird stuff in it[]!`.
• A property: n.prop, x.prop, rel.thisProperty, myFancyVariable.`(weird property name)`.

12

• A dynamic property: n["prop"], rel[n.city + n.zip], map[coll[0]].
• A parameter: $param, $0
• A list of expressions: ['a', 'b'], [1, 2, 3], ['a', 2, n.property, $param], [ ].
• A function call: length(p), nodes(p).
• An aggregate function: avg(x.prop), count(*).
• A path-pattern: (a)-->()<--(b).
• An operator application: 1 + 2 and 3 < 4.
• A predicate expression is an expression that returns true or false: a.prop = 'Hello', length(p) >
10, exists(a.name).
• A regular expression: a.name =~ 'Tim.*'
• A case-sensitive string matching expression: a.surname STARTS WITH 'Sven', a.surname ENDS WITH
'son' or a.surname CONTAINS 'son'
• A CASE expression.

2.3.2. Note on string literals
String literals can contain the following escape sequences:
Escape sequence Character
\t Tab
\b Backspace
\n Newline
\r Carriage return
\f Form feed
\' Single quote
\" Double quote
\\ Backslash
\uxxxx Unicode UTF-16 code point (4 hex
digits must follow the \u)
\Uxxxxxxxx Unicode UTF-32 code point (8 hex
digits must follow the \U)

2.3.3. CASE expressions
Generic conditional expressions may be expressed using the well-known CASE construct. Two variants
of CASE exist within Cypher: the simple form, which allows an expression to be compared against
multiple values, and the generic form, which allows multiple conditional statements to be expressed.
The following graph is used for the examples below:

13

A
name = 'Alice'
eyes = 'brown'
age = 38

KNOWS

KNOWS

C
name = 'Charlie'
eyes = 'green'
age = 53

KNOWS

B
name = 'Bob'
eyes = 'blue'
age = 25

KNOWS

MARRIED

E
D
name = 'Daniel'
eyes = 'brown'

array = ['one', 'two', 'three']
name = 'Eskil'
eyes = 'blue'
age = 41

Figure 2. Graph

Simple CASE form: comparing an expression against multiple values
The expression is calculated, and compared in order with the WHEN clauses until a match is found. If no
match is found, the expression in the ELSE clause is returned. However, if there is no ELSE case and no
match is found, null will be returned.
Syntax:
CASE test
WHEN value THEN result
[WHEN ...]
[ELSE default]
END

Arguments:
Name

Description

test

A valid expression.

value

An expression whose result will be compared to test.

result

This is the expression returned as output if value matches
test.

default

If no match is found, default is returned.

Query
MATCH (n)
RETURN
CASE n.eyes
WHEN 'blue'
THEN 1
WHEN 'brown'
THEN 2
ELSE 3 END AS result

Table 1. Result
result
2
1

14

result
3
2
1
5 rows

Generic CASE form: allowing for multiple conditionals to be expressed
The predicates are evaluated in order until a true value is found, and the result value is used. If no
match is found, the expression in the ELSE clause is returned. However, if there is no ELSE case and no
match is found, null will be returned.
Syntax:
CASE
WHEN predicate THEN result
[WHEN ...]
[ELSE default]
END

Arguments:
Name

Description

predicate

A predicate that is tested to find a valid alternative.

result

This is the expression returned as output if predicate
evaluates to true.

default

If no match is found, default is returned.

Query
MATCH (n)
RETURN
CASE
WHEN n.eyes = 'blue'
THEN 1
WHEN n.age < 40
THEN 2
ELSE 3 END AS result

Table 2. Result
result
2
1
3
3
1
5 rows

Distinguishing between when to use the simple and generic CASE forms
Owing to the close similarity between the syntax of the two forms, sometimes it may not be clear at
the outset as to which form to use. We illustrate this scenario by means of the following query, in

15

which there is an expectation that age_10_years_ago is -1 if n.age is null:
Query
MATCH (n)
RETURN n.name,
CASE n.age
WHEN n.age IS NULL THEN -1
ELSE n.age - 10 END AS age_10_years_ago

However, as this query is written using the simple CASE form, instead of age_10_years_ago being -1 for
the node named Daniel, it is null. This is because a comparison is made between n.age and n.age IS
NULL. As n.age IS NULL is a boolean value, and n.age is an integer value, the WHEN n.age IS NULL THEN
-1 branch is never taken. This results in the ELSE n.age - 10 branch being taken instead, returning
null.
Table 3. Result
n.name

age_10_years_ago

"Alice"

28

"Bob"

15

"Charlie"

43

"Daniel"



"Eskil"

31

5 rows

The corrected query, behaving as expected, is given by the following generic CASE form:
Query
MATCH (n)
RETURN n.name,
CASE
WHEN n.age IS NULL THEN -1
ELSE n.age - 10 END AS age_10_years_ago

We now see that the age_10_years_ago correctly returns -1 for the node named Daniel.
Table 4. Result
n.name

age_10_years_ago

"Alice"

28

"Bob"

15

"Charlie"

43

"Daniel"

-1

"Eskil"

31

5 rows

2.4. Variables
When you reference parts of a pattern or a query, you do so by naming them. The names you give the
different parts are called variables.
In this example:

16

MATCH (n)-->(b)
RETURN b

The variables are n and b.
Information regarding the naming of variables may be found here.
Variables are only visible in the same query part



Variables are not carried over to subsequent queries. If multiple query parts are
chained together using WITH, variables have to be listed in the WITH clause to be
carried over to the next part. For more information see WITH.

2.5. Reserved keywords
We provide here a listing of reserved words, grouped by the categories from which they are drawn, all
of which have a special meaning in Cypher. In addition to this, we list a number of words that are
reserved for future use.
These reserved words are not permitted to be used as identifiers in the following contexts:
• Variables
• Function names
• Parameters
If any reserved keyword is escaped — i.e. is encapsulated by backticks `, such as `AND` — it would
become a valid identifier in the above contexts.

2.5.1. Clauses
• CALL
• CREATE
• DELETE
• DETACH
• EXISTS
• FOREACH
• LOAD
• MATCH
• MERGE
• OPTIONAL
• REMOVE
• RETURN
• SET
• START
• UNION
• UNWIND
• WITH

17

2.5.2. Subclauses
• LIMIT
• ORDER
• SKIP
• WHERE
• YIELD

2.5.3. Modifiers
• ASC
• ASCENDING
• ASSERT
• BY
• CSV
• DESC
• DESCENDING
• ON

2.5.4. Expressions
• ALL
• CASE
• ELSE
• END
• THEN
• WHEN

2.5.5. Operators
• AND
• AS
• CONTAINS
• DISTINCT
• ENDS
• IN
• IS
• NOT
• OR
• STARTS
• XOR

18

2.5.6. Schema
• CONSTRAINT
• CREATE
• DROP
• EXISTS
• INDEX
• NODE
• KEY
• UNIQUE

2.5.7. Hints
• INDEX
• JOIN
• PERIODIC
• COMMIT
• SCAN
• USING

2.5.8. Literals
• false
• null
• true

2.5.9. Reserved for future use
• ADD
• DO
• FOR
• MANDATORY
• OF
• REQUIRE
• SCALAR

2.6. Parameters
• Introduction
• String literal
• Regular expression
• Case-sensitive string pattern matching
• Create node with properties
• Create multiple nodes with properties

19

• Setting all properties on a node
• SKIP and LIMIT
• Node id
• Multiple node ids
• Calling procedures
• Index value (explicit indexes)
• Index query (explicit indexes)

2.6.1. Introduction
Cypher supports querying with parameters. This means developers don’t have to resort to string
building to create a query. Additionally, parameters make caching of execution plans much easier for
Cypher, thus leading to faster query execution times.
Parameters can be used for:
• literals and expressions
• node and relationship ids
• for explicit indexes only: index values and queries
Parameters cannot be used for the following constructs, as these form part of the query structure that
is compiled into a query plan:
• property keys; so, MATCH (n) WHERE n.$param = 'something' is invalid
• relationship types
• labels
Parameters may consist of letters and numbers, and any combination of these, but cannot start with a
number or a currency symbol.
For details on using parameters via the Neo4j HTTP API, see the HTTP API documentation.
We provide below a comprehensive list of examples of parameter usage. In these examples,
parameters are given in JSON; the exact manner in which they are to be submitted depends upon the
driver being used.



It is recommended that the new parameter syntax $param is used, as the old syntax
{param} is deprecated and will be removed altogether in a later release.

2.6.2. String literal
Parameters
{
}

"name" : "Johan"

Query
MATCH (n:Person)
WHERE n.name = $name
RETURN n

20

You can use parameters in this syntax as well:
Parameters
{
}

"name" : "Johan"

Query
MATCH (n:Person { name: $name })
RETURN n

2.6.3. Regular expression
Parameters
{
"regex" : ".*h.*"
}

Query
MATCH (n:Person)
WHERE n.name =~ $regex
RETURN n.name

2.6.4. Case-sensitive string pattern matching
Parameters
{

"name" : "Michael"

}

Query
MATCH (n:Person)
WHERE n.name STARTS WITH $name
RETURN n.name

2.6.5. Create node with properties
Parameters
{

}

"props" : {
"name" : "Andy",
"position" : "Developer"
}

Query
CREATE ($props)

21

2.6.6. Create multiple nodes with properties
Parameters
{

}

"props" : [ {
"awesome" : true,
"name" : "Andy",
"position" : "Developer"
}, {
"children" : 3,
"name" : "Michael",
"position" : "Developer"
} ]

Query
UNWIND $props AS properties
CREATE (n:Person)
SET n = properties
RETURN n

2.6.7. Setting all properties on a node
Note that this will replace all the current properties.
Parameters
{

}

"props" : {
"name" : "Andy",
"position" : "Developer"
}

Query
MATCH (n:Person)
WHERE n.name='Michaela'
SET n = $props

2.6.8. SKIP and LIMIT
Parameters
{
}

"s" : 1,
"l" : 1

Query
MATCH (n:Person)
RETURN n.name
SKIP $s
LIMIT $l

2.6.9. Node id

22

Parameters
{
"id" : 0
}

Query
MATCH (n)
WHERE id(n)= $id
RETURN n.name

2.6.10. Multiple node ids
Parameters
{

"ids" : [ 0, 1, 2 ]

}

Query
MATCH (n)
WHERE id(n) IN $ids
RETURN n.name

2.6.11. Calling procedures
Parameters
{
}

"indexname" : ":Person(name)"

Query
CALL db.resampleIndex($indexname)

2.6.12. Index value (explicit indexes)
Parameters
{
}

"value" : "Michaela"

Query
START n=node:people(name = $value)
RETURN n

2.6.13. Index query (explicit indexes)

23

Parameters
{
"query" : "name:Bob"
}

Query
START n=node:people($query)
RETURN n

2.7. Operators
• Operators at a glance
• Aggregation operators
• Using the DISTINCT operator
• Property operators
• Statically accessing a property of a node or relationship using the . operator
• Filtering on a dynamically-computed property key using the [] operator
• Replacing all properties of a node or relationship using the = operator
• Mutating specific properties of a node or relationship using the += operator
• Mathematical operators
• Using the exponentiation operator ^
• Using the unary minus operator • Comparison operators
• Comparing two numbers
• Using STARTS WITH to filter names
• Boolean operators
• Using boolean operators to filter numbers
• String operators
• Using a regular expression with =~ to filter words
• Temporal operators
• Adding and subtracting a Duration to or from a temporal instant
• Adding and subtracting a Duration to or from another Duration
• Multiplying and dividing a Duration with or by a number
• Map operators
• Statically accessing the value of a nested map by key using the . operator"
• Dynamically accessing the value of a map by key using the [] operator and a parameter
• Using IN with [] on a nested list
• List operators
• Concatenating two lists using +

24

• Using IN to check if a number is in a list
• Using IN for more complex list membership operations
• Accessing elements in a list using the [] operator
• Dynamically accessing an element in a list using the [] operator and a parameter
• Equality and comparison of values
• Ordering and comparison of values
• Chaining comparison operations

2.7.1. Operators at a glance
Aggregation operators

DISTINCT

Property operators

. for static property access, [] for dynamic property
access, = for replacing all properties, += for mutating
specific properties

Mathematical operators

+, -, *, /, %, ^

Comparison operators

=, <>, <, >, <=, >=, IS NULL, IS NOT NULL

String-specific comparison operators

STARTS WITH, ENDS WITH, CONTAINS

Boolean operators

AND, OR, XOR, NOT

String operators

+ for concatenation, =~ for regex matching

Temporal operators

+ and - for operations between durations and temporal
instants/durations, * and / for operations between
durations and numbers

Map operators

. for static value access by key, [] for dynamic value access
by key

List operators

+ for concatenation, IN to check existence of an element in
a list, [] for accessing element(s) dynamically

2.7.2. Aggregation operators
The aggregation operators comprise:
• remove duplicates values: DISTINCT

Using the DISTINCT operator
Retrieve the unique eye colors from Person nodes.
Query
CREATE (a:Person { name: 'Anne', eyeColor: 'blue' }),(b:Person { name: 'Bill', eyeColor: 'brown'
}),(c:Person { name: 'Carol', eyeColor: 'blue' })
WITH [a, b, c] AS ps
UNWIND ps AS p
RETURN DISTINCT p.eyeColor

Even though both 'Anne' and 'Carol' have blue eyes, 'blue' is only returned once.
Table 5. Result
p.eyeColor
"blue"

25

p.eyeColor
"brown"
2 rows
Nodes created: 3
Properties set: 6
Labels added: 3

DISTINCT is commonly used in conjunction with aggregating functions.

2.7.3. Property operators
The property operators pertain to a node or a relationship, and comprise:
• statically access the property of a node or relationship using the dot operator: .
• dynamically access the property of a node or relationship using the subscript operator: []
• property replacement = for replacing all properties of a node or relationship
• property mutation operator += for setting specific properties of a node or relationship

Statically accessing a property of a node or relationship using the . operator
Query
CREATE (a:Person { name: 'Jane', livesIn: 'London' }),(b:Person { name: 'Tom', livesIn: 'Copenhagen' })
WITH a, b
MATCH (p:Person)
RETURN p.name

Table 6. Result
p.name
"Jane"
"Tom"
2 rows
Nodes created: 2
Properties set: 4
Labels added: 2

Filtering on a dynamically-computed property key using the [] operator
Query
CREATE (a:Restaurant { name: 'Hungry Jo', rating_hygiene: 10, rating_food: 7 }),(b:Restaurant { name:
'Buttercup Tea Rooms', rating_hygiene: 5, rating_food: 6 }),(c1:Category { name: 'hygiene' }),(c2:Category
{ name: 'food' })
WITH a, b, c1, c2
MATCH (restaurant:Restaurant),(category:Category)
WHERE restaurant["rating_" + category.name]> 6
RETURN DISTINCT restaurant.name

Table 7. Result
restaurant.name
"Hungry Jo"
1 row
Nodes created: 4
Properties set: 8
Labels added: 4

26

See Basic usage for more details on dynamic property access.



The behavior of the [] operator with respect to null is detailed here.

Replacing all properties of a node or relationship using the = operator
Query
CREATE (a:Person { name: 'Jane', age: 20 })
WITH a
MATCH (p:Person { name: 'Jane' })
SET p = { name: 'Ellen', livesIn: 'London' }
RETURN p.name, p.age, p.livesIn

All the existing properties on the node are replaced by those provided in the map; i.e. the name
property is updated from Jane to Ellen, the age property is deleted, and the livesIn property is added.
Table 8. Result
p.name

p.age

p.livesIn

"Ellen"



"London"

1 row
Nodes created: 1
Properties set: 5
Labels added: 1

See Replace all properties using a map and = for more details on using the property replacement
operator =.

Mutating specific properties of a node or relationship using the += operator
Query
CREATE (a:Person { name: 'Jane', age: 20 })
WITH a
MATCH (p:Person { name: 'Jane' })
SET p += { name: 'Ellen', livesIn: 'London' }
RETURN p.name, p.age, p.livesIn

The properties on the node are updated as follows by those provided in the map: the name property is
updated from Jane to Ellen, the age property is left untouched, and the livesIn property is added.
Table 9. Result
p.name

p.age

p.livesIn

"Ellen"

20

"London"

1 row
Nodes created: 1
Properties set: 4
Labels added: 1

See Mutate specific properties using a map and += for more details on using the property mutation
operator +=.

2.7.4. Mathematical operators
The mathematical operators comprise:

27

• addition: +
• subtraction or unary minus: • multiplication: *
• division: /
• modulo division: %
• exponentiation: ^

Using the exponentiation operator ^
Query
WITH 2 AS number, 3 AS exponent
RETURN number ^ exponent AS result

Table 10. Result
result
8.0
1 row

Using the unary minus operator Query
WITH -3 AS a, 4 AS b
RETURN b - a AS result

Table 11. Result
result
7
1 row

2.7.5. Comparison operators
The comparison operators comprise:
• equality: =
• inequality: <>
• less than: <
• greater than: >
• less than or equal to: <=
• greater than or equal to: >=
• IS NULL
• IS NOT NULL

String-specific comparison operators comprise:
• STARTS WITH: perform case-sensitive prefix searching on strings

28

• ENDS WITH: perform case-sensitive suffix searching on strings
• CONTAINS: perform case-sensitive inclusion searching in strings

Comparing two numbers
Query
WITH 4 AS one, 3 AS two
RETURN one > two AS result

Table 12. Result
result
true
1 row

See Equality and comparison of values for more details on the behavior of comparison operators, and
Using ranges for more examples showing how these may be used.

Using STARTS WITH to filter names
Query
WITH ['John', 'Mark', 'Jonathan', 'Bill'] AS somenames
UNWIND somenames AS names
WITH names AS candidate
WHERE candidate STARTS WITH 'Jo'
RETURN candidate

Table 13. Result
candidate
"John"
"Jonathan"
2 rows

String matching contains more information regarding the string-specific comparison operators as well
as additional examples illustrating the usage thereof.

2.7.6. Boolean operators
The boolean operators — also known as logical operators — comprise:
• conjunction: AND
• disjunction: OR,
• exclusive disjunction: XOR
• negation: NOT
Here is the truth table for AND, OR, XOR and NOT.
a

b

a AND b

a OR b

a XOR b

NOT a

false

false

false

false

false

true

false

null

false

null

null

true

29

a

b

a AND b

a OR b

a XOR b

NOT a

false

true

false

true

true

true

true

false

false

true

true

false

true

null

null

true

null

false

true

true

true

true

false

false

null

false

false

null

null

null

null

null

null

null

null

null

null

true

null

true

null

null

Using boolean operators to filter numbers
Query
WITH [2, 4, 7, 9, 12] AS numberlist
UNWIND numberlist AS number
WITH number
WHERE number = 4 OR (number > 6 AND number < 10)
RETURN number

Table 14. Result
number
4
7
9
3 rows

2.7.7. String operators
The string operators comprise:
• concatenating strings: +
• matching a regular expression: =~

Using a regular expression with =~ to filter words
Query
WITH ['mouse', 'chair', 'door', 'house'] AS wordlist
UNWIND wordlist AS word
WITH word
WHERE word =~ '.*ous.*'
RETURN word

Table 15. Result
word
"mouse"
"house"
2 rows

Further information and examples regarding the use of regular expressions in filtering can be found in

30

Regular expressions. In addition, refer to String-specific comparison operators comprise: for details on
string-specific comparison operators.

2.7.8. Temporal operators
Temporal operators comprise:
• adding a Duration to either a temporal instant or another Duration: +
• subtracting a Duration from either a temporal instant or another Duration: • multiplying a Duration with a number: *
• dividing a Duration by a number: /
The following table shows — for each combination of operation and operand type — the type of the
value returned from the application of each temporal operator:
Operator

Left-hand operand

Right-hand operand

Type of result

+

Temporal instant

Duration

The type of the temporal
instant

+

Duration

Temporal instant

The type of the temporal
instant

-

Temporal instant

Duration

The type of the temporal
instant

+

Duration

Duration

Duration

-

Duration

Duration

Duration

*

Duration

Number

Duration

*

Number

Duration

Duration

/

Duration

Number

Duration

Adding and subtracting a Duration to or from a temporal instant
Query
WITH localdatetime({ year:1984, month:10, day:11, hour:12, minute:31, second:14 }) AS aDateTime,
duration({ years: 12, nanoseconds: 2 }) AS aDuration
RETURN aDateTime + aDuration, aDateTime - aDuration

Table 16. Result
aDateTime + aDuration

aDateTime - aDuration

1996-10-11T12:31:14.000000002

1972-10-11T12:31:13.999999998

1 row

Components of a Duration that do not apply to the temporal instant are ignored. For example, when
adding a Duration to a Date, the hours, minutes, seconds and nanoseconds of the Duration are ignored
(Time behaves in an analogous manner):
Query
WITH date({ year:1984, month:10, day:11 }) AS aDate, duration({ years: 12, nanoseconds: 2 }) AS aDuration
RETURN aDate + aDuration, aDate - aDuration

Table 17. Result

31

aDate + aDuration

aDate - aDuration

1996-10-11

1972-10-11

1 row

Adding two durations to a temporal instant is not an associative operation. This is because nonexisting dates are truncated to the nearest existing date:
Query
RETURN (date("2011-01-31")+ duration("P1M"))+ duration("P12M") AS date1, date("2011-0131")+(duration("P1M")+ duration("P12M")) AS date2

Table 18. Result
date1

date2

2012-02-28

2012-02-29

1 row

Adding and subtracting a Duration to or from another Duration
Query
WITH duration({ years: 12, months: 5, days: 14, hours: 16, minutes: 12, seconds: 70, nanoseconds: 1 }) AS
duration1, duration({ months:1, days: -14, hours: 16, minutes: -12, seconds: 70 }) AS duration2
RETURN duration1, duration2, duration1 + duration2, duration1 - duration2

Table 19. Result
duration1

duration2

P12Y5M14DT16H13M10.0000000 P1M-14DT15H49M10S
01S

duration1 + duration2

duration1 - duration2

P12Y6MT32H2M20.000000001S

P12Y4M28DT24M0.000000001S

1 row

Multiplying and dividing a Duration with or by a number
These operations are interpreted simply as component-wise operations with overflow to smaller units
based on an average length of units in the case of division (and multiplication with fractions).
Query
WITH duration({ days: 14, minutes: 12, seconds: 70, nanoseconds: 1 }) AS aDuration
RETURN aDuration, aDuration * 2, aDuration / 3

Table 20. Result
aDuration

aDuration * 2

aDuration / 3

P14DT13M10.000000001S

P28DT26M20.000000002S

P4DT16H4M23.333333333S

1 row

2.7.9. Map operators
The map operators comprise:
• statically access the value of a map by key using the dot operator: .

32

• dynamically access the value of a map by key using the subscript operator: []



The behavior of the [] operator with respect to null is detailed in The [] operator
and null.

Statically accessing the value of a nested map by key using the . operator
Query
WITH { person: { name: 'Anne', age: 25 }} AS p
RETURN p.person.name

Table 21. Result
p.person.name
"Anne"
1 row

Dynamically accessing the value of a map by key using the [] operator and a
parameter
A parameter may be used to specify the key of the value to access:
Parameters
{
"myKey" : "name"
}

Query
WITH { name: 'Anne', age: 25 } AS a
RETURN a[$myKey] AS result

Table 22. Result
result
"Anne"
1 row

More details on maps can be found in Maps.

2.7.10. List operators
The list operators comprise:
• concatenating lists l1 and l2: [l1] + [l2]
• checking if an element e exists in a list l: e IN [l]
• dynamically accessing an element(s) in a list using the subscript operator: []



The behavior of the IN and [] operators with respect to null is detailed here.

33

Concatenating two lists using +
Query
RETURN [1,2,3,4,5]+[6,7] AS myList

Table 23. Result
myList
[1,2,3,4,5,6,7]
1 row

Using IN to check if a number is in a list
Query
WITH [2, 3, 4, 5] AS numberlist
UNWIND numberlist AS number
WITH number
WHERE number IN [2, 3, 8]
RETURN number

Table 24. Result
number
2
3
2 rows

Using IN for more complex list membership operations
The general rule is that the IN operator will evaluate to true if the list given as the right-hand operand
contains an element which has the same type and contents (or value) as the left-hand operand. Lists
are only comparable to other lists, and elements of a list l are compared pairwise in ascending order
from the first element in l to the last element in l.
The following query checks whether or not the list [2, 1] is an element of the list [1, [2, 1], 3]:
Query
RETURN [2, 1] IN [1,[2, 1], 3] AS inList

The query evaluates to true as the right-hand list contains, as an element, the list [1, 2] which is of
the same type (a list) and contains the same contents (the numbers 2 and 1 in the given order) as the
left-hand operand. If the left-hand operator had been [1, 2] instead of [2, 1], the query would have
returned false.
Table 25. Result
inList
true
1 row

At first glance, the contents of the left-hand operand and the right-hand operand appear to be the
same in the following query:

34

Query
RETURN [1, 2] IN [1, 2] AS inList

However, IN evaluates to false as the right-hand operand does not contain an element that is of the
same type — i.e. a list — as the left-hand-operand.
Table 26. Result
inList
false
1 row

The following query can be used to ascertain whether or not a list llhs — obtained from, say, the
labels() function — contains at least one element that is also present in another list lrhs:
MATCH (n)
WHERE size([l IN labels(n) WHERE l IN ['Person', 'Employee'] | 1]) > 0
RETURN count(n)

As long as labels(n) returns either Person or Employee (or both), the query will return a value greater
than zero.

Accessing elements in a list using the [] operator
Query
WITH ['Anne', 'John', 'Bill', 'Diane', 'Eve'] AS names
RETURN names[1..3] AS result

The square brackets will extract the elements from the start index 1, and up to (but excluding) the end
index 3.
Table 27. Result
result
["John","Bill"]
1 row

Dynamically accessing an element in a list using the [] operator and a
parameter
A parameter may be used to specify the index of the element to access:
Parameters
{
}

"myIndex" : 1

Query
WITH ['Anne', 'John', 'Bill', 'Diane', 'Eve'] AS names
RETURN names[$myIndex] AS result

35

Table 28. Result
result
"John"
1 row

Using IN with [] on a nested list
IN can be used in conjunction with [] to test whether an element exists in a nested list:
Parameters
{
"myIndex" : 1
}

Query
WITH [[1, 2, 3]] AS l
RETURN 3 IN l[0] AS result

Table 29. Result
result
true
1 row

More details on lists can be found in Lists in general.

2.7.11. Equality and comparison of values
Equality
Cypher supports comparing values (see Values and types) by equality using the = and <> operators.
Values of the same type are only equal if they are the same identical value (e.g. 3 = 3 and "x" <>
"xy").
Maps are only equal if they map exactly the same keys to equal values and lists are only equal if they
contain the same sequence of equal values (e.g. [3, 4] = [1+2, 8/2]).
Values of different types are considered as equal according to the following rules:
• Paths are treated as lists of alternating nodes and relationships and are equal to all lists that
contain that very same sequence of nodes and relationships.
• Testing any value against null with both the = and the <> operators always is null. This includes
null = null and null <> null. The only way to reliably test if a value v is null is by using the
special v IS NULL, or v IS NOT NULL equality operators.
All other combinations of types of values cannot be compared with each other. Especially, nodes,
relationships, and literal maps are incomparable with each other.
It is an error to compare values that cannot be compared.

36

2.7.12. Ordering and comparison of values
The comparison operators <=, < (for ascending) and >=, > (for descending) are used to compare values
for ordering. The following points give some details on how the comparison is performed.
• Numerical values are compared for ordering using numerical order (e.g. 3 < 4 is true).
• The special value java.lang.Double.NaN is regarded as being larger than all other numbers.
• String values are compared for ordering using lexicographic order (e.g. "x" < "xy").
• Boolean values are compared for ordering such that false < true.
• Comparison of spatial values:
• Point values can only be compared within the same Coordinate Reference System
(CRS) — otherwise, the result will be null.
• For two points a and b within the same CRS, a is considered to be greater than b if a.x > b.x
and a.y > b.y (and a.z > b.z for 3D points).
• a is considered less than b if a.x < b.x and a.y < b.y (and a.z < b.z for 3D points).
• If none if the above is true, the points are considered incomparable and any comparison
operator between them will return null.
• Ordering of spatial values:
• ORDER BY requires all values to be orderable.
• Points are ordered after arrays and before temporal types.
• Points of different CRS are ordered by the CRS code (the value of SRID field). For the currently
supported set of Coordinate Reference Systems this means the order: 4326, 4979, 7302, 9157
• Points of the same CRS are ordered by each coordinate value in turn, x first, then y and finally
z.
• Note that this order is different to the order returned by the spatial index, which will be the
order of the space filling curve.
• Comparison of temporal values:
• Temporal instant values are comparable within the same type. An instant is considered less
than another instant if it occurs before that instant in time, and it is considered greater than if
it occurs after.
• Instant values that occur at the same point in time — but that have a different time zone — are
not considered equal, and must therefore be ordered in some predictable way. Cypher
prescribes that, after the primary order of point in time, instant values be ordered by effective
time zone offset, from west (negative offset from UTC) to east (positive offset from UTC). This
has the effect that times that represent the same point in time will be ordered with the time
with the earliest local time first. If two instant values represent the same point in time, and
have the same time zone offset, but a different named time zone (this is possible for DateTime
only, since Time only has an offset), these values are not considered equal, and ordered by the
time zone identifier, alphabetically, as its third ordering component.
• Duration values cannot be compared, since the length of a day, month or year is not known
without knowing which day, month or year it is. Since Duration values are not comparable, the
result of applying a comparison operator between two Duration values is null. If the type, point
in time, offset, and time zone name are all equal, then the values are equal, and any difference
in order is impossible to observe.
• Ordering of temporal values:
• ORDER BY requires all values to be orderable.
• Temporal instances are ordered after spatial instances and before strings.

37

• Comparable values should be ordered in the same order as implied by their comparison order.
• Temporal instant values are first ordered by type, and then by comparison order within the
type.
• Since no complete comparison order can be defined for Duration values, we define an order
for ORDER BY specifically for Duration:
• Duration values are ordered by normalising all components as if all years were 365.2425
days long (PT8765H49M12S), all months were 30.436875 (1/12 year) days long (PT730H29M06S),
and all days were 24 hours long [1: The 365.2425 days per year comes from the frequency
of leap years. A leap year occurs on a year with an ordinal number divisible by 4, that is not
divisible by 100, unless it divisible by 400. This means that over 400 years there are ((365 *
4 + 1) * 25 - 1) * 4 + 1 = 146097 days, which means an average of 365.2425 days per
year.].
• Comparing for ordering when one argument is null (e.g. null < 3 is null).

2.7.13. Chaining comparison operations
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y AND y <= z.
Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators,
then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z.
Note that a op1 b op2 c does not imply any kind of comparison between a and c, so that, e.g., x < y >
z is perfectly legal (although perhaps not elegant).
The example:
MATCH (n) WHERE 21 < n.age <= 30 RETURN n

is equivalent to
MATCH (n) WHERE 21 < n.age AND n.age <= 30 RETURN n

Thus it will match all nodes where the age is between 21 and 30.
This syntax extends to all equality and inequality comparisons, as well as extending to chains longer
than three.
For example:
a < b = c <= d <> e

Is equivalent to:
a < b AND b = c AND c <= d AND d <> e

For other comparison operators, see Comparison operators.

2.8. Comments
To add comments to your queries, use double slash. Examples:

38

MATCH (n) RETURN n //This is an end of line comment

MATCH (n)
//This is a whole line comment
RETURN n

MATCH (n) WHERE n.property = '//This is NOT a comment' RETURN n

2.9. Patterns
• Introduction
• Patterns for nodes
• Patterns for related nodes
• Patterns for labels
• Specifying properties
• Patterns for relationships
• Variable-length pattern matching
• Assigning to path variables

2.9.1. Introduction
Patterns and pattern-matching are at the very heart of Cypher, so being effective with Cypher requires
a good understanding of patterns.
Using patterns, you describe the shape of the data you’re looking for. For example, in the MATCH clause
you describe the shape with a pattern, and Cypher will figure out how to get that data for you.
The pattern describes the data using a form that is very similar to how one typically draws the shape
of property graph data on a whiteboard: usually as circles (representing nodes) and arrows between
them to represent relationships.
Patterns appear in multiple places in Cypher: in MATCH, CREATE and MERGE clauses, and in pattern
expressions.
Each of these is described in more detail in:
• MATCH
• OPTIONAL MATCH
• CREATE
• MERGE
• Using path patterns in WHERE

2.9.2. Patterns for nodes
The very simplest 'shape' that can be described in a pattern is a node.
pair of parentheses, and is typically given a name.
For example:

A node is described using a

(a)

This simple pattern describes a single node, and names that node using the variable a.

39

2.9.3. Patterns for related nodes
A more powerful construct is a pattern that describes multiple nodes and relationships between
them. Cypher patterns describe relationships by employing an arrow between two nodes. For
example:
(a)-->(b)

This pattern describes a very simple data shape: two nodes, and a single relationship from one to the
other. In this example, the two nodes are both named as a and b respectively, and the relationship is
'directed': it goes from a to b.
This manner of describing nodes and relationships can be extended to cover an arbitrary number of
nodes and the relationships between them, for example:
(a)-->(b)<--(c)

Such a series of connected nodes and relationships is called a "path".
Note that the naming of the nodes in these patterns is only necessary should one need to refer to the
same node again, either later in the pattern or elsewhere in the Cypher query. If this is not necessary,
then the name may be omitted, as follows:
(a)-->()<--(c)

2.9.4. Patterns for labels
In addition to simply describing the shape of a node in the pattern, one can also describe attributes.
The most simple attribute that can be described in the pattern is a label that the node must have. For
example:
(a:User)-->(b)

One can also describe a node that has multiple labels:
(a:User:Admin)-->(b)

2.9.5. Specifying properties
Nodes and relationships are the fundamental structures in a graph. Neo4j uses properties on both of
these to allow for far richer models.
Properties can be expressed in patterns using a map-construct: curly brackets surrounding a number
of key-expression pairs, separated by commas. E.g. a node with two properties on it would look like:
(a {name: 'Andy', sport: 'Brazilian Ju-Jitsu'})

A relationship with expectations on it is given by:
(a)-[{blocked: false}]->(b)

40

When properties appear in patterns, they add an additional constraint to the shape of the data. In the
case of a CREATE clause, the properties will be set in the newly-created nodes and relationships. In the
case of a MERGE clause, the properties will be used as additional constraints on the shape any existing
data must have (the specified properties must exactly match any existing data in the graph). If no
matching data is found, then MERGE behaves like CREATE and the properties will be set in the newly
created nodes and relationships.
Note that patterns supplied to CREATE may use a single parameter to specify properties, e.g: CREATE
(node $paramName). This is not possible with patterns used in other clauses, as Cypher needs to know
the property names at the time the query is compiled, so that matching can be done effectively.

2.9.6. Patterns for relationships
The simplest way to describe a relationship is by using the arrow between two nodes, as in the
previous examples. Using this technique, you can describe that the relationship should exist and the
directionality of it. If you don’t care about the direction of the relationship, the arrow head can be
omitted, as exemplified by:
(a)--(b)

As with nodes, relationships may also be given names. In this case, a pair of square brackets is used to
break up the arrow and the variable is placed between. For example:
(a)-[r]->(b)

Much like labels on nodes, relationships can have types. To describe a relationship with a specific type,
you can specify this as follows:
(a)-[r:REL_TYPE]->(b)

Unlike labels, relationships can only have one type. But if we’d like to describe some data such that the
relationship could have any one of a set of types, then they can all be listed in the pattern, separating
them with the pipe symbol | like this:
(a)-[r:TYPE1|TYPE2]->(b)

Note that this form of pattern can only be used to describe existing data (ie. when using a pattern with
MATCH or as an expression). It will not work with CREATE or MERGE, since it’s not possible to create a
relationship with multiple types.
As with nodes, the name of the relationship can always be omitted, as exemplified by:
(a)-[:REL_TYPE]->(b)

2.9.7. Variable-length pattern matching

41



Variable length pattern matching in versions 2.1.x and earlier does not enforce
relationship uniqueness for patterns described within a single MATCH clause. This
means that a query such as the following: MATCH (a)-[r]->(b), p = (a)-[]->(c)
RETURN *, relationships(p) AS rs may include r as part of the rs set. This
behavior has changed in versions 2.2.0 and later, in such a way that r will
be excluded from the result set, as this better adheres to the rules of
relationship uniqueness as documented here Uniqueness. If you have a query
pattern that needs to retrace relationships rather than ignoring them as the
relationship uniqueness rules normally dictate, you can accomplish this using
multiple match clauses, as follows: MATCH (a)-[r]->(b) MATCH p = (a)-[]->(c)
RETURN *, relationships(p). This will work in all versions of Neo4j that support the
MATCH clause, namely 2.0.0 and later.

Rather than describing a long path using a sequence of many node and relationship descriptions in a
pattern, many relationships (and the intermediate nodes) can be described by specifying a length in
the relationship description of a pattern. For example:
(a)-[*2]->(b)

This describes a graph of three nodes and two relationship, all in one path (a path of length 2). This is
equivalent to:
(a)-->()-->(b)

A range of lengths can also be specified: such relationship patterns are called 'variable length
relationships'. For example:
(a)-[*3..5]->(b)

This is a minimum length of 3, and a maximum of 5. It describes a graph of either 4 nodes and 3
relationships, 5 nodes and 4 relationships or 6 nodes and 5 relationships, all connected together in a
single path.
Either bound can be omitted. For example, to describe paths of length 3 or more, use:
(a)-[*3..]->(b)

To describe paths of length 5 or less, use:
(a)-[*..5]->(b)

Both bounds can be omitted, allowing paths of any length to be described:
(a)-[*]->(b)

As a simple example, let’s take the graph and query below:

42

name = 'Anders'

KNOWS

name = 'Dilshad'

KNOWS

KNOWS

name = 'Cesar'

KNOWS

name = 'Filipa'

name = 'Becky'

KNOWS

KNOWS

name = 'George'

Figure 3. Graph
Query
MATCH (me)-[:KNOWS*1..2]-(remote_friend)
WHERE me.name = 'Filipa'
RETURN remote_friend.name

Table 30. Result
remote_friend.name
"Dilshad"
"Anders"
2 rows

This query finds data in the graph which a shape that fits the pattern: specifically a node (with the
name property 'Filipa') and then the KNOWS related nodes, one or two hops away. This is a typical
example of finding first and second degree friends.
Note that variable length relationships cannot be used with CREATE and MERGE.

2.9.8. Assigning to path variables
As described above, a series of connected nodes and relationships is called a "path". Cypher allows
paths to be named using an identifer, as exemplified by:
p = (a)-[*3..5]->(b)

You can do this in MATCH, CREATE and MERGE, but not when using patterns as expressions.

2.10. Temporal (Date/Time) values
Cypher has built-in support for handling temporal values, and the underlying database
supports storing these temporal values as properties on nodes and relationships.
• Introduction
• Time zones
• Temporal instants
• Specifying temporal instants
• Specifying dates

43

• Specifying times
• Specifying time zones
• Examples
• Accessing components of temporal instants
• Durations
• Specifying durations
• Examples
• Accessing components of durations
• Examples
• Temporal indexing
Refer to Temporal functions - instant types for information regarding temporal
functions allowing for the creation and manipulation of temporal values.



Refer to Temporal operators for information regarding temporal operators.
Refer to Ordering and comparison of values for information regarding the
comparison and ordering of temporal values.

2.10.1. Introduction
The following table depicts the temporal value types and supported components:
Type

Date support

Time support

Time zone support

Date

X

Time

X

X

LocalTime

X

DateTime

X

X

LocalDateTime

X

X

Duration

-

-

X

-

Date, Time, LocalTime, DateTime and LocalDateTime 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 only captures
the amount of time between two instants, and thus does not encapsulate a start time and end time.

2.10.2. Time zones
Time zones are represented either as an offset from UTC, or as a logical identifier of a named time zone
(these are based on the IANA time zone database (https://www.iana.org/time-zones)). In either case the
time is stored as UTC internally, and the time zone offset is only applied when the time is presented.
This means that temporal instants can be ordered without taking time zone into account. If, however,
two times are identical in UTC, then they are ordered by timezone.
When creating a time using a named time zone, the offset from UTC is computed from the rules in the
time zone database to create a time instant in UTC, and to ensure the named time zone is a valid one.

44

It is possible for time zone rules to change in the IANA time zone database. For example, there could
be alterations to the rules for daylight savings time in a certain area. If this occurs after the creation of
a temporal instant, the presented time could differ from the originally-entered time, insofar as the
local timezone is concerned. However, the absolute time in UTC would remain the same.
There are three ways of specifying a time zone in Cypher:
• Specifying the offset from UTC in hours and minutes (ISO 8601 (https://en.wikipedia.org/wiki/ISO_8601))
• Specifying a named time zone
• Specifying both the offset and the time zone name (with the requirement that these match)
The named time zone form uses the rules of the IANA time zone database to manage daylight savings
time (DST).
The default time zone of the database can be configured using the configuration option
db.temporal.timezone. This configuration option influences the creation of temporal types for the
following functions:
• Getting the current date and time without specifying a time zone.
• Creating a temporal type from its components without specifying a time zone.
• Creating a temporal type by parsing a string without specifying a time zone.
• Creating a temporal type by combining or selecting values that do not have a time zone
component, and without specifying a time zone.
• Truncating a temporal value that does not have a time zone component, and without specifying a
time zone.

2.10.3. Temporal instants
Specifying temporal instants
A temporal instant consists of three parts; the date, the time, and the timezone. These parts may then
be combined to produce the various temporal value types. Literal characters are denoted in bold.
Temporal instant type

Composition of parts

Date



Time


Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.3
Linearized                      : No
Page Count                      : 434
Page Mode                       : UseOutlines
Title                           : The Neo4j Cypher Manual v3.5
Creator                         : Asciidoctor PDF 1.5.0.alpha.11, based on Prawn 1.3.0
Producer                        : Asciidoctor PDF 1.5.0.alpha.11, based on Prawn 1.3.0
Create Date                     : 2018:12:10 12:46:32+00:00
Modify Date                     : 2018:12:10 12:46:32+00:00
EXIF Metadata provided by EXIF.tools

Navigation menu