Cypher has good support for lists.
Lists in general
A literal list is created by using brackets and separating the elements in the list with commas.
Query
RETURN [0,1,2,3,4,5,6,7,8,9] AS list
Result
list |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN [0,1,2,3,4,5,6,7,8,9] AS list
In our examples, we’ll use the range function. It gives you a list containing all numbers between given start and end numbers. Range is inclusive in both ends.
To access individual elements in the list, we use the square brackets again. This will extract from the start index and up to but not including the end index.
Query
RETURN range(0,10)[3]
Result
range(0,10)[3] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[3]
You can also use negative numbers, to start from the end of the list instead.
Query
RETURN range(0,10)[-3]
Result
range(0,10)[-3] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[-3]
Finally, you can use ranges inside the brackets to return ranges of the list.
Query
RETURN range(0,10)[0..3]
Result
range(0,10)[0..3] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[0..3]
Query
RETURN range(0,10)[0..-5]
Result
range(0,10)[0..-5] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[0..-5]
Query
RETURN range(0,10)[-5..]
Result
range(0,10)[-5..] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[-5..]
Query
RETURN range(0,10)[..4]
Result
range(0,10)[..4] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[..4]
Note Out-of-bound slices are simply truncated, but out-of-bound single elements return |
Query
RETURN range(0,10)[15]
Result
range(0,10)[15] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[15]
Query
RETURN range(0,10)[5..15]
Result
range(0,10)[5..15] |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN range(0,10)[5..15]
You can get the size of a list like this:
Query
RETURN size(range(0,10)[0..3])
Result
size(range(0,10)[0..3]) |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN size(range(0,10)[0..3])
List comprehension
List comprehension is a syntactic construct available in Cypher for creating a list based on existing lists. It follows the form of the mathematical set-builder notation (set comprehension) instead of the use of map and filter functions.
Query
RETURN [x IN range(0,10) WHERE x % 2 = 0 | x^3] AS result
Result
result |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN [x IN range(0,10) WHERE x % 2 = 0 | x^3] AS result
Either the WHERE
part, or the expression, can be omitted, if you only want to filter or map respectively.
Query
RETURN [x IN range(0,10) WHERE x % 2 = 0] AS result
Result
result |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN [x IN range(0,10) WHERE x % 2 = 0] AS result
Query
RETURN [x IN range(0,10)| x^3] AS result
Result
result |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN [x IN range(0,10)| x^3] AS result
Literal maps
From Cypher, you can also construct maps. Through REST you will get JSON objects; in Java they will be java.util.Map<String,Object>
.
Query
RETURN { key : "Value", listKey: [{ inner: "Map1" }, { inner: "Map2" }]}
Result
{ key : "Value", listKey: [ { inner: "Map1" }, { inner: "Map2" } ] } |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; RETURN { key : "Value", listKey: [{ inner: "Map1" }, { inner: "Map2" }]}
Map Projection
Cypher supports a concept called "map projections". It allows for easily constructing 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 coma separated map elements, enclosed by {
and }
.
map_variable { map_element, [, ...n] }
A map element projects one or more key value pair to the map projection. There exists four different types of map projection elements:
-
Property selector - Projects the property name as the key, and the value from the
map_variable
as the value for the projection. -
Literal entry - This is a key value pair, with the value being arbitrary expression
key : <expression>
. - Variable selector - Projects an variable, with the variable name as the key, and the value the variable is pointing to as the value of the projection. It’s syntax is just the variable.
-
All-properties selector - projects all key value pair from the
map_variable
value.
Note that if the map_variable
points to a null value, the whole map projection will evaluate to null.
Examples of map projections
Find Charlie Sheen and return data about him and the movies he has acted in.
This example shows an example of map projection with a literal entry, which in turn also uses map projection inside the aggregating collect()
.
Query
MATCH (actor:Person { name:'Charlie Sheen' })-[:ACTED_IN]->(movie:Movie) RETURN actor { .name, .realName, movies: collect(movie { .title, .year })}
Result
actor |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; MATCH (actor:Person { name:'Charlie Sheen' })-[:ACTED_IN]->(movie:Movie) RETURN actor { .name, .realName, movies: collect(movie { .title, .year })}
Find all persons that have acted in movies, and show number for each. This example introduces an variable with the count, and uses an variable selector to project the value.
Query
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie) WITH actor, count(movie) AS nrOfMovies RETURN actor { .name, nrOfMovies }
Result
actor |
---|
2 rows |
|
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie) WITH actor, count(movie) AS nrOfMovies RETURN actor { .name, nrOfMovies }
Again, focusing on Charlie Sheen, this time returning all properties from the node.
Here we use an all-properties selector to project all the node properties, and additionally, explicitly project the property age
.
Since this property does not exist on the node, a null value is projected instead.
Query
MATCH (actor:Person { name:'Charlie Sheen' }) RETURN actor { .*, .age }
Result
actor |
---|
1 row |
|
Try this query live create (_0:`Movie` {`name`:"WallStreet", `title`:"Wall Street", `year`:1987}) create (_1:`Movie` {`name`:"ApocalypseNow", `title`:"Apocalypse Now", `year`:1979}) create (_2:`Person` {`name`:"Charlie Sheen", `realName`:"Carlos Irwin Estévez"}) create (_3:`Person` {`name`:"Martin Sheen"}) create (_4:`Movie` {`name`:"RedDawn", `title`:"Red Dawn", `year`:1984}) create (_2)-[:`ACTED_IN`]->(_1) create (_2)-[:`ACTED_IN`]->(_4) create (_2)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_0) create (_3)-[:`ACTED_IN`]->(_1) ; MATCH (actor:Person { name:'Charlie Sheen' }) RETURN actor { .*, .age }