映射表达式

Map 表达式允许您在 Cypher® 中操作和查询 MAP(映射)值。

keys() 函数可用于返回 MAP 中所有键的 LIST(列表)。

示例图

以下图表用于下方的示例

Example graph featuring connections between person and movie nodes

要重新创建该图,请在空的 Neo4j 数据库中运行以下查询

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 运算符

Cypher 包含两个 Map 运算符:

  • 通过键静态访问值:点运算符 (.)。

  • 通过键动态访问值:下标运算符 ([])。

静态访问 MAP

通过在 . 运算符后指定键,可以静态访问 MAP 值。

静态 MAP 值访问
WITH {a: 10, b: 20, c: 30} AS map
RETURN map.a AS firstValue,
       map.c AS lastValue
结果
firstValue lastValue

10

30

行:1

要静态访问嵌套 MAP 中的值,请使用链式 . 运算符。每个 . 运算符都会向嵌套结构深处遍历一层。

嵌套 MAP 值的静态访问
WITH {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

10

200

行:1

节点和关系的属性作为键值对存储在 MAP 中。因此,可以使用 . 运算符静态访问属性。

静态访问节点属性
MATCH (p:Person)
RETURN p AS nodePropertyMaps,
       p.name AS accessedMapValue
结果
nodePropertyMaps accessedMapValue

(:Person {nationality: "Canadian", name: "Keanu Reeves"})

"Keanu Reeves"

(:Person {name: "Carrie-Anne Moss"})

"Carrie-Anne Moss"

行:2

动态访问 MAP

要动态访问 MAP 值,请使用下标运算符 []。键可以由变量或参数提供。

使用变量动态访问 MAP
WITH {a: 10, b: 20, c: 30} AS map,
     'a' AS dynamicKey
RETURN map[dynamicKey] AS dynamicValue
结果
dynamicValue

10

行:1

参数
{
  "dynamicKey" : "a"
}
使用参数动态访问 MAP
WITH {a: 10, b: 20, c: 30} AS map
RETURN map[$dynamicKey] AS dynamicValue
结果
dynamicValue

10

行:1

动态访问嵌套 MAP
WITH {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

300

行:1

通过使用 列表推导式 (list comprehension),可以动态地从 MAP 中访问多个值。此查询遍历 LIST dynamicKeys 并从 map 中检索它们对应的值。

动态 MAP 值访问和列表推导式
WITH {a: 10, b: 20, c: 30} AS map,
     ['a', 'c'] AS dynamicKeys
RETURN [key IN dynamicKeys | map[key]] AS dynamicValue
结果
dynamicValue

[10, 30]

行:1

动态访问节点属性值
MATCH (p:Person)
LET dynamicValue = 'name'
RETURN p[dynamicValue] AS names
结果
names

"Keanu Reeves"

"Carrie-Anne Moss"

行:2

使用 [] 运算符引用 MAP 中不存在的键将返回 null

动态引用不存在的 MAP
WITH {a: 10, b: 20, c: 30} AS map,
     'z' AS dynamicKey
RETURN map[dynamicKey] AS dynamicValue
结果
dynamicValue

null

行:1

Map 投影 (Map projection)

Cypher 支持 Map 投影,允许从节点、关系和其他 MAP 值创建 MAP 值。

Map 投影以绑定到要投影的 MAP 的变量开始,并包含一个由花括号 {} 包围的逗号分隔的 MAP 键主体。每个 map 元素指定一个包含在结果映射投影中的键值对。

语法
mapVariable {mapElement [, ...n]}

mapElement 可以是以下之一:

  • 键选择器 (key selector):引用 MAP 中的键并提取相应的值。

  • 字面量条目 (literal entry):使用自定义键值对,其中键是指定的,值通过表达式定义。

  • 变量选择器 (variable selector):投影变量的值,使用变量名作为键,使用其引用的值作为值。

  • 全映射投影 (all-map projection):投影 mapVariable 中的所有键值对。

映射中的键名必须为 STRING 类型。
如果 mapVariablenull,则投影结果为 null
示例 1. 使用键选择器的 Map 投影

当需要从 MAP 中提取特定键值对时,使用键选择器的 Map 投影非常有用。

基础示例
WITH {a: 10, b: 20, c: 30} AS map
RETURN map{.a, .c} AS projectedMap
结果
projectedMap

{a: 10, c: 30}

行:1

在下方的查询中,使用带有属性选择器的 Map 投影来 collect(收集)每部电影的 title(标题)和 release(发布)年份。

使用键选择器的 Map 投影
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN p.name AS actor, collect(m{.title, .released}) AS movies
结果
actor movies

"Keanu Reeves"

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

"Carrie-Anne Moss"

[{title: "The Matrix Resurrections", released: 2021}, {title: "The Matrix Revolutions", released: 2003}, {title: "The Matrix Reloaded", released: 2003}, {title: "The Matrix", released: 1999}]

行:2

示例 2. 使用字面量条目的 Map 投影

当您想向投影的 MAP 值添加自定义值而不修改原始数据结构时,使用字面量条目的 Map 投影非常有用。

基础示例
WITH {a: 10, b: 20, c: 30} AS map
RETURN map{a: map.a, valueSum: map.a + map.b + map.c} AS projectedMap
结果
projectedMap

{a: 10, valueSum: 60}

行:1

此查询使用带有字面量条目的 Map 投影,其中 size(movies) 表达式计算了 Keanu Reeves 参演电影的总数。

使用字面量条目的 Map 投影
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

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

行:1

示例 3. 使用变量选择器的 Map 投影

当您想基于变量名投影值时,使用变量选择器的 Map 投影非常有用。

基础示例
MATCH (keanu:Person {name: 'Keanu Reeves'})
LET dob = date('1964-09-02'), birthPlace =  'Beirut, Lebanon'
RETURN keanu{.name, dob, birthPlace} AS projectedKeanu
结果
projectedKeanu

{name: "Keanu Reeves", birthPlace: "Beirut, Lebanon", dob: 1964-09-02}

行:1

下方的查询查找图中所有与 Movie 节点具有一个或多个 ACTED_IN 类型关系的 Person 节点。它使用 count() 函数计算每个 Person 节点以此方式连接的 Movie 节点数量,并使用变量选择器投影该计数的值。

使用变量选择器的 Map 投影
MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)
WITH actor, count(movie) AS totalMovies
RETURN actor{totalMovies, .name} AS nameAndMovies
结果
nameAndMovies

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

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

行:2

示例 4. 使用全映射投影的 Map 投影

当您想投影 MAP 中的所有键值对而不显式列出它们时,使用全映射投影的 Map 投影非常有用。

基础示例
WITH {a: 10, b: 20, c: 30} AS map
RETURN map{.*} AS projectedMap
结果
projectedMap

{a: 10, b: 20, c: 30}

行:1

下方的查询返回 Keanu Reeves 节点的所有属性。使用全映射选择器来投影所有节点属性。

使用全映射选择器的 Map 投影
MATCH (keanu:Person {name: 'Keanu Reeves'})
RETURN keanu{.*} AS allKeanuProperties
结果
AllKeanuProperties

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

行:1