Map expressions
Example graph
The following graph is used for the examples below:
To recreate the graph, run the following query against an empty Neo4j database:
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)
Map operators
Cypher contains two map operators:
-
Statically access a value by key: dot operator (
.
). -
Dynamically access a value by key: subscript operator (
[]
).
Statically access a MAP
value
MAP
values can be accessed statically by specifying a key after the .
operator.
MAP
value accessWITH {a: 10, b: 20, c: 30} AS map
RETURN map.a AS firstValue,
map.c AS lastValue
firstValue | lastValue |
---|---|
|
|
Rows: 1 |
To statically access a value in a nested MAP
, use chained .
operators.
Each .
operator traverses one level deeper into the nested structure.
MAP
valueWITH {a: 10, b: 20, c: 30, innerMap: {x: 100, y: 200, z: 300}} AS map
RETURN map.a AS firstOuterValue,
map.innerMap.y AS secondInnerValue
firstOuterValue | secondInnerValue |
---|---|
|
|
Rows: 1 |
Node and relationship properties are stored as key-value pairs in a MAP
.
Properties can, therefore, be statically accessed using the .
operator.
MATCH (p:Person)
RETURN p AS nodePropertyMaps,
p.name AS accessedMapValue
nodePropertyMaps | accessedMapValue |
---|---|
|
|
|
|
Rows: 2 |
Dynamically access a MAP
value
To dynamically access a MAP
value, use the subscript operator, []
.
The key can be provided by a variable or a parameter.
MAP
value using a variableWITH {a: 10, b: 20, c: 30} AS map,
'a' AS dynamicKey
RETURN map[dynamicKey] AS dynamicValue
dynamicValue |
---|
|
Rows: 1 |
{
"dynamicKey" : 'a'
}
MAP
value using a parameterWITH {a: 10, b: 20, c: 30} AS map
RETURN map[$dynamicKey] AS dynamicValue
dynamicValue |
---|
|
Rows: 1 |
MAP
valueWITH {a: 10, b: 20, c: 30, innerMap: {x: 100, y: 200, z: 300}} AS map,
'z' AS dynamicInnerKey
RETURN map.innerMap[dynamicInnerKey] AS dynamicInnerValue
dynamicInnerValue |
---|
|
Rows: 1 |
It is possible to dynamically access multiple values from a MAP
by using list comprehension.
This query iterates over the LIST
dynamicKeys
and retrieves their corresponding values from the map
.
MAP
value access and list comprehensionWITH {a: 10, b: 20, c: 30} AS map,
['a', 'c'] AS dynamicKeys
RETURN [key IN dynamicKeys | map[key]] AS dynamicValue
dynamicValue |
---|
|
Rows: 1 |
MATCH (p:Person)
LET dynamicValue = 'name'
RETURN p[dynamicValue] AS names
names |
---|
|
|
Rows: 2 |
Referencing a non-existent key in the MAP
with the []
operator will return NULL
.
MAP
keyWITH {a: 10, b: 20, c: 30} AS map,
'z' AS dynamicKey
RETURN map[dynamicKey] AS dynamicValue
dynamicValue |
---|
|
Rows: 1 |
Map projection
Cypher supports map projections, which allow the creation of MAP
values from nodes, relationships, and other MAP
values.
A map projection begins with the variable bound to the MAP
to be projected from, and contains a body of comma-separated MAP
keys, enclosed by curly braces, {}
.
Each map element specifies a key-value pair that is included in the resulting map projection.
mapVariable {mapElement [, ...n]}
mapElement
can be one of the following:
-
An key selector that references a key in a
MAP
and pulls the corresponding value. -
A literal entry that uses a custom key-value pair where the key is specified and the value is defined using an expression.
-
A variable selector that projects the value of a variable, using the variable name as the key, and the value it references as the value.
-
An all-map projection that projects all key-value pairs from
mapVariable
.
The key names in a map must be of type STRING .If mapVariable is NULL , the projection evaluates to NULL .
|
Map projections with a key selector are useful when you need to extract specific key-value pairs from a MAP
.
WITH {a: 10, b: 20, c: 30} AS map
RETURN map{.a, .c} AS projectedMap
projectedMap |
---|
|
Rows: 1 |
In the below query, a map projection with property selectors is used to collect
only the title
and release
year of each movie.
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN p.name AS actor, collect(m{.title, .released}) AS movies
actor | movies |
---|---|
|
|
|
|
Rows: 2 |
Map projections with a literal entry are useful when you want to add custom values to a projected MAP
value without modifying the original data structure.
WITH {a: 10, b: 20, c: 30} AS map
RETURN map{a: map.a, valueSum: map.a + map.b + map.c} AS projectedMap
projectedMap |
---|
|
Rows: 1 |
This query uses a map projection with a literal entry, where the size(movies)
expression calculates the total number of movies Keanu Reeves
has acted in.
MATCH (keanu:Person {name: 'Keanu Reeves'})-[:ACTED_IN]->(movie:Movie)
WITH keanu, collect(movie) AS movies
RETURN keanu {.name, totalMovies: size(movies)} AS keanuDetails
keanuDetails |
---|
|
Rows: 1 |
Map projection with a variable selector is useful when you want to project values based on a variable name.
MATCH (keanu:Person {name: 'Keanu Reeves'})
LET dob = date('1964-09-02'), birthPlace = 'Beirut, Lebanon'
RETURN keanu{.name, dob, birthplace} AS projectedKeanu
projectedKeanu |
---|
|
Rows: 1 |
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 totalMovies
RETURN actor{totalMovies, .name} AS nameAndMovies
nameAndMovies |
---|
|
|
Rows: 2 |
Map projection with an all-map projection is useful when you want to project all key-value pairs from a MAP
without explicitly listing them.
WITH {a: 10, b: 20, c: 30} AS map
RETURN map{.*} AS projectedMap
projectedMap |
---|
|
Rows: 1 |
The below query returns all properties from the Keanu Reeves
node.
An all-map selector is used to project all the node properties.
MATCH (keanu:Person {name: 'Keanu Reeves'})
RETURN keanu{.*} AS allKeanuProperties
AllKeanuProperties |
---|
|
Rows: 1 |