列表表达式

列表表达式允许您在 Cypher® 中操作和查询 LIST 值。

有关评估为 LIST 值的更多表达式,请参阅 列表函数
有关如何使用 IN 运算符检查 LIST 中成员资格的信息,请参阅 谓词 → 列表运算符

示例图

以下图形用于下面的示例

list expressions graph

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

CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager', skills: ['Java', 'Python']}),
       (cecil:Person {name: 'Cecil', age: 25, role: 'Software developer', skills: ['Java', 'Python']}),
       (cecilia:Person {name: 'Cecilia', age: 31, role: 'Software developer', skills: ['JavaScript', 'TypeScript']}),
       (charlie:Person {name: 'Charlie', age: 61, role: 'Security engineer', skills: ['C++', 'Python']}),
       (daniel:Person {name: 'Daniel', age: 39, role: 'Director', skills: ['Ruby', 'Go']}),
       (eskil:Person {name: 'Eskil', age: 39, role: 'CEO', skills: ['Java', 'C++', 'Python']}),

       (cecil)-[:WORKS_FOR]->(alice),
       (cecilia)-[:WORKS_FOR]->(alice),
       (charlie)-[:WORKS_FOR]->(daniel),
       (alice)-[:WORKS_FOR]->(daniel),
       (daniel)-[:WORKS_FOR]->(eskil)

列表元素访问

下标运算符 [] 可用于访问 LIST 中的特定元素。[0] 指的是 LIST 中的第一个元素,[1] 指的是第二个,以此类推。[-1] 指的是 LIST 中的最后一个元素,[-2] 指的是倒数第二个元素,以此类推。

访问 LIST 中的单个元素
WITH [1, 2, 3, 4] AS list
RETURN list[0] AS firstElement,
       list[2] AS thirdElement,
       list[-1] AS finalElement
结果
第一个元素 第三个元素 最后一个元素

1

3

4

行数: 1

LIST 中元素的索引可以参数化。

参数
{
  "myIndex" : 1
}
使用参数访问 LIST 元素
WITH [1, 2, 3, 4] AS list
RETURN list[$myIndex] AS secondElement
结果
第二个元素

2

行数: 1

访问嵌套 LIST 中的 LIST
WITH [[1, 2], [3, 4], [5, 6]] AS nestedList
RETURN nestedList[1] AS secondList
结果
第二个列表

[3, 4]

行数: 1

访问嵌套 LIST 中的特定元素
WITH [[1, 2], [3, 4], [5, 6]] AS nestedList
RETURN nestedList[1] AS secondList,
       nestedList[1][0] AS firstElementOfSecondList
结果
第二个列表 第二个列表的第一个元素

[3, 4]

3

行数: 1

列表元素访问中的索引可以是任何表达式,包括变量。

使用变量作为索引访问列表元素
WITH [[1, 2], [3, 4], [5, 6]] AS nestedList, 2 AS listIndex
RETURN nestedList[listIndex] AS thirdList,
       nestedList[listIndex][listIndex - 1] AS secondElementOfThirdList
结果
第三个列表 第三个列表的第二个元素

[5, 6]

6

行数: 1

IN 运算符用于检查 LIST 成员资格,可以与 [] 一起使用来测试元素是否存在于嵌套 LIST 中。

检查嵌套 LIST 中的成员资格
WITH [[1, 2, 3], [4, 5, 6]] AS nestedList
RETURN 3 IN nestedList[0] AS elementPresent
结果
元素存在

TRUE

行数: 1

尝试引用 LIST 边界之外的元素将返回 null,尝试从空 LIST 访问元素也将返回 null

越界和空 LIST 访问
WITH [1, 2, 3, 4] AS list, [] AS emptyList
RETURN list[5] AS outOfBound, emptyList[0] AS emptyAccess
结果
越界 空访问

null

null

行数: 1

列表切片

如果下标运算符中提供了范围,则 LIST 值可以被切片。范围的边界使用两个点 (..) 分隔。这允许提取 LIST 的子集而不是单个元素。列表切片在范围的开始处是包含性的,但在结束处是排他性的(例如 list[start..end] 包含 start,但不包含 end)。

LIST 的切片操作
WITH [1, 2, 3, 4, 5, 6] AS list
RETURN list[2..4] AS middleElements,
       list[..2] AS noLowerBound,
       list[2..] AS noUpperBound
结果
中间元素 无下界 无上界

[3, 4]

[1, 2]

[3, 4, 5, 6]

行数: 1

列表切片中的负索引从 LIST 的末尾引用元素;..-1 排除最后一个元素,..-2 排除最后两个元素,依此类推。

负索引和列表切片
WITH [1, 2, 3, 4, 5, 6] AS list
RETURN list[..-1] AS finalElementRemoved,
       list[..-2] AS finalTwoElementsRemoved,
       list[-3..-1] AS removedFirstThreeAndLast
结果
最后一个元素已删除 最后两个元素已删除 已删除前三个和最后一个

[1, 2, 3, 4, 5]

[1, 2, 3, 4]

[4, 5]

行数: 1

切片嵌套 LIST 值时,务必指定切片哪一层。下面的示例切片外部 LIST 并返回前两个嵌套 LIST 值。

切片外部 LIST
WITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
RETURN nestedList[0..2] AS slicedNestedList
结果
切片嵌套列表

[[1, 2, 3], [4, 5, 6]]

行数: 1

切片内部 LIST 值需要两个 [] 运算符;第一个 [] 访问外部 LIST 中的元素,而第二个则切片或访问内部 LIST 中的元素。

切片内部 LIST
WITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
RETURN nestedList[1][0..2] AS slicedInnerList
结果
切片内部列表

[4, 5]

行数: 1

访问特定元素或元素范围也可以与 + 运算符结合使用,以创建新的 LIST,其中包含插入到现有 LIST 值特定部分的元素。

将元素插入到 LIST 的特定位置
WITH [1, 3, 4] AS list
RETURN list[0] + [2] + list[1..] AS newList
结果
新列表

[1, 2, 3, 4]

行数: 1

列表连接

Cypher 包含两个列表连接运算符:||+|| 符合 GQL 标准,而 + 不符合。

使用 ||+ 进行列表连接
RETURN [1,2] || [3,4] AS list1,
       [1,2] + [3,4] AS list2
结果
列表1 列表2

[1, 2, 3, 4]

[1, 2, 3, 4]

行数: 1

连接两个 LIST 属性
MATCH (cecil:Person {name: 'Cecil'}), (cecilia:Person {name: 'Cecilia'})
RETURN cecil.skills || cecilia.skills AS combinedSkills
结果
组合技能

["Java", "Python", "JavaScript", "TypeScript"]

行数: 1

如果 null 是连接 LIST 的一部分,那么 null 将成为新 LIST 的一部分。

连接包含 nullLIST
RETURN [1, 2] || [3, null] AS listWithNull
结果
包含 Null 的列表

[1, 2, 3, null]

行数: 1

有关连接 LIST 值时移除 null 值的信息,请参阅 null、列表连接和列表推导

向列表添加元素

+ 运算符可以将元素添加到 LIST 值的开头或结尾。使用 || 运算符无法实现此操作。

将元素添加到 LIST 的开头和结尾
WITH [1, 2, 3, 4] AS list
RETURN 0 + list AS newBeginning,
       list + 5 AS newEnd
结果
新开头 新结尾

[0, 1, 2, 3, 4]

[1, 2, 3, 4, 5]

行数: 1

要将 LIST 值插入到嵌套 LIST 中,添加的 LIST 本身必须是嵌套的。如果添加的 LIST 未嵌套,则其元素被视为单个元素,而如果它已嵌套,则它在嵌套 LIST 中保持 LIST 结构。

LIST 值添加到嵌套 LIST
WITH [[1, 2], [3, 4]] AS nestedList
RETURN nestedList + [5, 6] AS nonNestedAddition,
       nestedList + [[5, 6]] AS nestedAddition
结果
非嵌套添加 嵌套添加

[[1, 2], [3, 4], 5, 6]

[[1, 2], [3, 4], [5, 6]]

行数: 1

将元素添加到 LIST 属性的开头
MATCH (cecil:Person {name: 'Cecil'})
SET cecil.skills = "Cypher" + cecil.skills
RETURN cecil.skills AS skillsList
结果
技能列表

["Cypher", "Java", "Python"]

行数: 1

列表推导

列表推导用于通过迭代现有 LIST 值并根据特定条件或操作转换元素来创建新的 LIST 值。此过程有效地将原始 LIST 中的每个元素映射到新值。结果是一个由转换后的元素组成的新 LIST

语法
[item IN list [WHERE predicate] | [expression]]

迭代步骤 (item IN list) 确保逐个访问 list 的每个元素,而 expression 可选择对每个 item 应用转换,创建包含修改后元素的新 LIST 值。

不带表达式的列表推导
RETURN [x IN range(0,10) WHERE x % 2 = 0] AS result
结果
结果

[0, 2, 4, 6, 8, 10]

行数: 1

不带过滤的列表推导
RETURN [x IN range(0,5) | x * 10] AS result
结果
结果

[0, 10, 20, 30, 40, 50]

行数: 1

带有表达式和过滤的列表推导
WITH [1, 2, 3, 4, 5] AS list
RETURN [n IN list WHERE n > 2 | n] AS filteredList
结果
过滤列表

[3, 4, 5]

行数: 1

下一个示例展示了如何使用列表推导通过索引映射 LISTrange() 函数用于生成从 0LIST 的最后一个有效索引的索引,然后将每个索引与其对应的 LIST 值组合成一个 STRING 值。结果是一个 STRING 值列表,格式为 'index: value'

使用索引映射列表元素
WITH [1,2,3,4] AS list
RETURN [listIndex IN range(0, size(list)-1) | toString(listIndex) || ': ' || toString(list[listIndex])] AS mappedListElements
结果
映射列表元素

["0: 1", "1: 2", "2: 3", "3: 4"]

行数: 1

下面的查询迭代每个 Person 节点的 skills 属性,并通过将 " expert" 连接到每个 skills 中的元素来创建一个新的 LIST

使用列表推导修改 LIST 属性
MATCH (p:Person) WHERE p.skills IS NOT NULL
ORDER BY p.name
RETURN p.name AS name,
      [skill IN p.skills | skill + " expert"] AS modifiedSkills
结果
名称 修改后的技能

"Alice"

["Java expert", "Python expert"]

"Cecil"

["Cypher expert", "Java expert", "Python expert"]

"Cecilia"

["JavaScript expert", "TypeScript expert"]

"Charlie"

["C++ expert", "Python expert"]

"Daniel"

["Ruby expert", "Go expert"]

"Eskil"

["Java expert", "C++ expert", "Python expert"]

行数: 6

下一个查询使用 collect() 函数将所有 Person 节点收集到一个 LIST 中,然后 WHERE 'Python' IN person.skills 谓词过滤该列表以仅包含 skills 属性包含 Python 的节点。

WHERE 谓词的列表推导
MATCH (p:Person)
RETURN [person IN collect(p) WHERE 'Python' IN person.skills | person.name] AS pythonExperts
结果
Python 专家

["Alice", "Cecil", "Charlie", "Eskil"]

行数: 1

列表推导可用于在连接 LIST 值时移除任何未知的 null 值。

列表推导以在列表连接期间移除 null
RETURN [x IN ([1, null, 3] || [null, 5, null]) WHERE x IS NOT NULL] AS listWithoutNull
结果
不带 null 的列表

[1, 3, 5]

行数: 1

模式推导

模式推导用于通过匹配图模式并对匹配的元素应用条件来创建新的 LIST 值,返回自定义投影。

语法
[pattern [WHERE predicate] | expression]

下面的查询使用模式推导将 Alice 的所有 employees 的名称提取到 LIST 中,从而检索一个员工姓名列表。

固定长度模式上的模式推导
MATCH (alice:Person {name: 'Alice'})
RETURN [(employee:Person)-[:WORKS_FOR]->(alice) | employee.name] AS employees
结果
员工

["Cecil", "Cecilia"]

行数: 1

模式推导可以包含 WHERE 谓词。

包含 WHERE 谓词的模式推导
MATCH (alice:Person {name: 'Alice'})
RETURN [(employee:Person)-[:WORKS_FOR]->(alice) WHERE employee.age > 30 | employee.name || ', ' || toString(employee.age)] AS employeesAbove30
结果
30岁以上员工

["Cecilia, 31"]

行数: 1

模式推导也可以匹配可变长度模式。但是,模式推导不支持符合 GQL 标准的量词语法

不允许:使用 GQL 量词语法的可变长度模式推导
MATCH (cecil:Person {name: 'Cecil'})
RETURN [(cecil)-[:WORKS_FOR]->+(superior:Person) | superior.skills] AS superiorsSkills

模式推导只支持可变长度关系语法。下面的查询使用模式推导来收集 Cecil 上方链中所有上级的技能。 reduce() 函数将这些技能连接成一个 LIST,然后使用 UNWIND 展平此 LIST,最后返回新 LIST 中的不同技能。

允许:使用可变长度关系语法的可变长度模式推导
MATCH (cecil:Person {name: 'Cecil'})
WITH [(cecil)-[:WORKS_FOR*]->(superior:Person) | superior.skills] AS allSuperiorsSkills
WITH reduce(accumulatedSkills = [], superiorSkills IN allSuperiorsSkills | accumulatedSkills || superiorSkills) AS allSkills
UNWIND allSkills AS superiorsSkills
RETURN collect(DISTINCT superiorsSkills) AS distinctSuperiorsSkills
结果
独特上级技能

["Java", "Python", "Ruby", "Go", "C++"]

行数: 1

© . All rights reserved.