Maps

Cypher® supports the construction of maps. This section first discusses literal maps and then moves on to map projection.

Information regarding property access operators such as . and [] can be found here. The behavior of the [] operator with respect to null is detailed here.

Literal maps

The key names in a map must be literals. If returned through an HTTP API call, a JSON object will be returned. If returned in Java, an object of type java.util.Map<String,Object> will be returned.

Query
RETURN {key: 'Value', listKey: [{inner: 'Map1'}, {inner: 'Map2'}]} AS map
Table 1. Result
map

{'listKey': [{'inner': 'Map1'}, {'inner': 'Map2'}], 'key': 'Value'}

Rows: 1

Map projection

Cypher supports map projections, which allows for the construction of map projections from nodes, relationships, and other map values.

A map projection begins with the variable bound to the graph entity to be projected from, and contains a body of comma-separated map elements, enclosed by { and }.

Map projection
map_variable {map_element, [, ...n]}

A map element projects one or more key-value pairs to the map projection. There exist four different types of map projection elements:

  • Property selector - Projects the property name as the key, and the value from the map_variable as the value for the projection.

  • Literal entry - This is a key-value pair, with the value being an arbitrary expression key: <expression>.

  • Variable selector - Projects a variable, with the variable name as the key, and the value the variable is pointing to as the value of the projection. Its syntax is just the variable.

  • All-properties selector - projects all key-value pairs from the map_variable value.

The following conditions apply:

  • If the map_variable points to a null value, the whole map projection will evaluate to null.

  • The key names in a map must be of type STRING.

Example graph

The following graph is used for the examples below:

values and types maps graph

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)

Examples

The below query finds the Keanu Reeves node and the movies he has acted in. It is an example of a map projection with a literal entry, which in turn also uses map projection inside the aggregating collect() function.

Query
MATCH (keanu:Person {name: 'Keanu Reeves'})-[:ACTED_IN]->(movie:Movie)
WITH keanu, collect(movie{.title, .released}) AS movies
RETURN keanu{.name, movies: movies}
Table 2. Result
keanu

{movies: [{title: "The Devils Advocate", released: 1997}, {title: "The Matrix Revolutions", released: 2003}, {title: "The Matrix Resurrections", released: 2021}, {title: "The Matrix Reloaded", released: 2003}, {title: "The Matrix", released: 1999}], name: "Keanu Reeves"}

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.

Query
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)
WITH actor, count(movie) AS numberOfMovies
RETURN actor{.name, numberOfMovies}
Table 3. Result
actor

{numberOfMovies: 5, name: "Keanu Reeves"}

{numberOfMovies: 4, name: "Carrie-Anne Moss"}

Rows: 2

The below query returns all properties from the Keanu Reeves node. An all-properties selector is used to project all the node properties, and additionally, explicitly project the property age. Since this property does not exist on the node Keanu Reeves, a null value is projected instead.

Query
MATCH (keanu:Person {name: 'Keanu Reeves'})
RETURN keanu{.*, .age}
Table 4. Result
keanu

{nationality: "Canadian", name: "Keanu Reeves", age: null}

Rows: 1

The below query is an example of statically accessing individual map members using the . operator:

Query
WITH {age: 58, profession: 'Actor'} as keanuStats
RETURN keanuStats.profession AS profession
Table 5. Result
profession

"Actor"

Rows: 1