### 3.2.9. Maps

Cypher has solid support for maps.

The following graph is used for the examples below:

#### 3.2.9.1. 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' }]}``

Table 3.32. Result
{ key: 'Value', listKey: [{ inner: 'Map1' }, { inner: 'Map2' }]}

1 row

`{listKey -> [{inner -> "Map1"},{inner -> "Map2"}], key -> "Value"}`

Try this query live.  CREATE (charlie:Person {name: 'Charlie Sheen', realName: 'Carlos Irwin Estévez'}), (martin:Person {name: 'Martin Sheen'}), (wallstreet:Movie {title: 'Wall Street', year: 1987}), (reddawn:Movie {title: 'Red Dawn', year: 1984}), (apocalypsenow:Movie {title: 'Apocalypse Now', year: 1979}), (charlie)-[:ACTED_IN]->(wallstreet), (charlie)-[:ACTED_IN]->(reddawn), (charlie)-[:ACTED_IN]->(apocalypsenow), (martin)-[:ACTED_IN]->(wallstreet), (martin)-[:ACTED_IN]->(apocalypsenow) RETURN { key: 'Value', listKey: [{ inner: 'Map1' }, { inner: 'Map2' }]}

#### 3.2.9.2. 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 comma-separated map elements, enclosed by `{` and `}`.

`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 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.

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 })}``````

Table 3.33. Result
actor

1 row

```{name -> "Charlie Sheen", movies -> [{title -> "Apocalypse Now", year -> 1979},{title -> "Red Dawn", year -> 1984},{title -> "Wall Street", year -> 1987}], realName -> "Carlos Irwin Estévez"}```

Try this query live.  CREATE (charlie:Person {name: 'Charlie Sheen', realName: 'Carlos Irwin Estévez'}), (martin:Person {name: 'Martin Sheen'}), (wallstreet:Movie {title: 'Wall Street', year: 1987}), (reddawn:Movie {title: 'Red Dawn', year: 1984}), (apocalypsenow:Movie {title: 'Apocalypse Now', year: 1979}), (charlie)-[:ACTED_IN]->(wallstreet), (charlie)-[:ACTED_IN]->(reddawn), (charlie)-[:ACTED_IN]->(apocalypsenow), (martin)-[:ACTED_IN]->(wallstreet), (martin)-[:ACTED_IN]->(apocalypsenow) 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 a variable selector to project the value.

Query.

``````MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)
WITH actor, count(movie) AS nrOfMovies
RETURN actor { .name, nrOfMovies }``````

Table 3.34. Result
actor

2 rows

`{name -> "Martin Sheen", nrOfMovies -> 2}`

`{name -> "Charlie Sheen", nrOfMovies -> 3}`

Try this query live.  CREATE (charlie:Person {name: 'Charlie Sheen', realName: 'Carlos Irwin Estévez'}), (martin:Person {name: 'Martin Sheen'}), (wallstreet:Movie {title: 'Wall Street', year: 1987}), (reddawn:Movie {title: 'Red Dawn', year: 1984}), (apocalypsenow:Movie {title: 'Apocalypse Now', year: 1979}), (charlie)-[:ACTED_IN]->(wallstreet), (charlie)-[:ACTED_IN]->(reddawn), (charlie)-[:ACTED_IN]->(apocalypsenow), (martin)-[:ACTED_IN]->(wallstreet), (martin)-[:ACTED_IN]->(apocalypsenow) 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 }``````

Table 3.35. Result
actor

1 row

`{name -> "Charlie Sheen", realName -> "Carlos Irwin Estévez", age -> <null>}`

Try this query live.  CREATE (charlie:Person {name: 'Charlie Sheen', realName: 'Carlos Irwin Estévez'}), (martin:Person {name: 'Martin Sheen'}), (wallstreet:Movie {title: 'Wall Street', year: 1987}), (reddawn:Movie {title: 'Red Dawn', year: 1984}), (apocalypsenow:Movie {title: 'Apocalypse Now', year: 1979}), (charlie)-[:ACTED_IN]->(wallstreet), (charlie)-[:ACTED_IN]->(reddawn), (charlie)-[:ACTED_IN]->(apocalypsenow), (martin)-[:ACTED_IN]->(wallstreet), (martin)-[:ACTED_IN]->(apocalypsenow) MATCH (actor:Person {name: 'Charlie Sheen'}) RETURN actor{.*, .age}