Lists
Cypher® includes comprehensive support for lists. This section first describes lists in general, and then discusses how to use list comprehension and pattern comprehension in lists.
Lists in general
A literal list is created by using brackets and separating the elements in the list with commas.
RETURN [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] AS list
| list |
|---|
|
Rows: 1 |
A list can consist of different value types.
RETURN [0, "hello", 3.14, null] AS list
| list |
|---|
|
Rows: 1 |
Lists are indexed by 0 in Cypher. To access individual elements in a list, use square brackets. This extracts from the start index and up to, but not including, the end index.
For example:
---
WITH [5,1,7] AS list
RETURN list[2]
---
| list[2] |
|---|
|
Rows: 1 |
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)[3] AS list
| list |
|---|
|
Rows: 1 |
It is also possible to use negative numbers, to start from the end of the list instead.
RETURN range(0, 10)[-3] AS list
| list |
|---|
|
Rows: 1 |
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 |
|---|
|
Rows: 1 |
RETURN range(0, 10)[0..-5] AS list
| list |
|---|
|
Rows: 1 |
RETURN range(0, 10)[-5..] AS list
| list |
|---|
|
Rows: 1 |
RETURN range(0, 10)[..4] AS list
| list |
|---|
|
Rows: 1 |
Out-of-bound slices are simply truncated, but out-of-bound single elements return null.
RETURN range(0, 10)[15] AS list
| list |
|---|
|
Rows: 1 |
RETURN range(0, 10)[5..15] AS list
| list |
|---|
|
Rows: 1 |
The size of a list can be obtained as follows:
RETURN size(range(0, 10)[0..3]) AS list
| list |
|---|
|
Rows: 1 |
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.
Example graph
The following graph is used for examples below:
To recreate the graph, run the following query against an empty Neo4j database:
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 |
|---|
|
Rows: 1 |
The whole predicate, including the WHERE keyword, is optional and may be omitted.
Storing lists as properties
It is possible to store homogenous lists of simple values as properties.
For example, the following query creates a list from the title properties of the Movie nodes connected to Keanu Reeves.
It then sets that list as a resume property on Keanu Reeves.
MATCH (keanu:Person {name: 'Keanu Reeves'})
WITH keanu,[(keanu)-->(b:Movie) | b.title] AS movieTitles
SET keanu.resume = movieTitles
RETURN keanu.resume
| keanu.resume |
|---|
|
Rows: 1 |
It is not, however, possible to store heterogenous lists as properties.
For example, the following query, which tries to set a list including both the title and the released properties as the resume property of Keanu Reeves will fail.
This is because the title property values are stored as strings, while the released property values are stored as integers.
MATCH (keanu:Person {name: 'Keanu Reeves'})
WITH keanu,[(keanu)-->(b:Movie) | b.title] + [(keanu)-->(b:Movie) | b.released] AS movieTitles
SET keanu.resume = movieTitles
RETURN keanu.resume
Neo4j only supports a subset of Cypher types for storage as singleton or array properties. Please refer to section cypher/syntax/values of the manual for more details.
List comprehension
List comprehension is a syntactic construct available in Cypher for creating a list based on existing lists.
For example, the following query returns a new list from the previously created resume property (a list of strings) of Keanu Reeves:
MATCH (keanu:Person {name:'Keanu Reeves'})
RETURN [x IN keanu.resume WHERE x contains 'The Matrix'] AS matrixList
| matrixList |
|---|
|
Rows: 1 |
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 |
|---|
|
Rows: 1 |
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 |
|---|
|
Rows: 1 |
RETURN [x IN range(0,10) | x^3 ] AS result
| result |
|---|
|
Rows: 1 |