列表表达式
列表表达式允许您在 Cypher® 中操作和查询 LIST 值。
有关评估为 LIST 值的更多表达式,请参阅 列表函数。
有关如何使用 IN 运算符检查 LIST 中成员资格的信息,请参阅 谓词 → 列表运算符。
示例图
以下图形用于下面的示例
要重新创建图形,请对空的 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 |
||
LIST 中元素的索引可以参数化。
{
"myIndex" : 1
}
LIST 元素WITH [1, 2, 3, 4] AS list
RETURN list[$myIndex] AS secondElement
| 第二个元素 |
|---|
|
行数: 1 |
LIST 中的 LISTWITH [[1, 2], [3, 4], [5, 6]] AS nestedList
RETURN nestedList[1] AS secondList
| 第二个列表 |
|---|
|
行数: 1 |
LIST 中的特定元素WITH [[1, 2], [3, 4], [5, 6]] AS nestedList
RETURN nestedList[1] AS secondList,
nestedList[1][0] AS firstElementOfSecondList
| 第二个列表 | 第二个列表的第一个元素 |
|---|---|
|
|
行数: 1 |
|
列表元素访问中的索引可以是任何表达式,包括变量。
WITH [[1, 2], [3, 4], [5, 6]] AS nestedList, 2 AS listIndex
RETURN nestedList[listIndex] AS thirdList,
nestedList[listIndex][listIndex - 1] AS secondElementOfThirdList
| 第三个列表 | 第三个列表的第二个元素 |
|---|---|
|
|
行数: 1 |
|
IN 运算符用于检查 LIST 成员资格,可以与 [] 一起使用来测试元素是否存在于嵌套 LIST 中。
LIST 中的成员资格WITH [[1, 2, 3], [4, 5, 6]] AS nestedList
RETURN 3 IN nestedList[0] AS elementPresent
| 元素存在 |
|---|
|
行数: 1 |
尝试引用 LIST 边界之外的元素将返回 null,尝试从空 LIST 访问元素也将返回 null。
LIST 访问WITH [1, 2, 3, 4] AS list, [] AS emptyList
RETURN list[5] AS outOfBound, emptyList[0] AS emptyAccess
| 越界 | 空访问 |
|---|---|
|
|
行数: 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
| 中间元素 | 无下界 | 无上界 |
|---|---|---|
|
|
|
行数: 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 |
||
切片嵌套 LIST 值时,务必指定切片哪一层。下面的示例切片外部 LIST 并返回前两个嵌套 LIST 值。
LISTWITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
RETURN nestedList[0..2] AS slicedNestedList
| 切片嵌套列表 |
|---|
|
行数: 1 |
切片内部 LIST 值需要两个 [] 运算符;第一个 [] 访问外部 LIST 中的元素,而第二个则切片或访问内部 LIST 中的元素。
LISTWITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
RETURN nestedList[1][0..2] AS slicedInnerList
| 切片内部列表 |
|---|
|
行数: 1 |
访问特定元素或元素范围也可以与 + 运算符结合使用,以创建新的 LIST,其中包含插入到现有 LIST 值特定部分的元素。
LIST 的特定位置WITH [1, 3, 4] AS list
RETURN list[0] + [2] + list[1..] AS newList
| 新列表 |
|---|
|
行数: 1 |
列表连接
Cypher 包含两个列表连接运算符:|| 和 +。|| 符合 GQL 标准,而 + 不符合。
|| 和 + 进行列表连接RETURN [1,2] || [3,4] AS list1,
[1,2] + [3,4] AS list2
| 列表1 | 列表2 |
|---|---|
|
|
行数: 1 |
|
LIST 属性MATCH (cecil:Person {name: 'Cecil'}), (cecilia:Person {name: 'Cecilia'})
RETURN cecil.skills || cecilia.skills AS combinedSkills
| 组合技能 |
|---|
|
行数: 1 |
如果 null 是连接 LIST 的一部分,那么 null 将成为新 LIST 的一部分。
null 的 LISTRETURN [1, 2] || [3, null] AS listWithNull
| 包含 Null 的列表 |
|---|
|
行数: 1 |
有关连接 LIST 值时移除 null 值的信息,请参阅 null、列表连接和列表推导。
向列表添加元素
+ 运算符可以将元素添加到 LIST 值的开头或结尾。使用 || 运算符无法实现此操作。
LIST 的开头和结尾WITH [1, 2, 3, 4] AS list
RETURN 0 + list AS newBeginning,
list + 5 AS newEnd
| 新开头 | 新结尾 |
|---|---|
|
|
行数: 1 |
|
要将 LIST 值插入到嵌套 LIST 中,添加的 LIST 本身必须是嵌套的。如果添加的 LIST 未嵌套,则其元素被视为单个元素,而如果它已嵌套,则它在嵌套 LIST 中保持 LIST 结构。
LIST 值添加到嵌套 LISTWITH [[1, 2], [3, 4]] AS nestedList
RETURN nestedList + [5, 6] AS nonNestedAddition,
nestedList + [[5, 6]] AS nestedAddition
| 非嵌套添加 | 嵌套添加 |
|---|---|
|
|
行数: 1 |
|
LIST 属性的开头MATCH (cecil:Person {name: 'Cecil'})
SET cecil.skills = "Cypher" + cecil.skills
RETURN cecil.skills AS skillsList
| 技能列表 |
|---|
|
行数: 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
| 结果 |
|---|
|
行数: 1 |
RETURN [x IN range(0,5) | x * 10] AS result
| 结果 |
|---|
|
行数: 1 |
WITH [1, 2, 3, 4, 5] AS list
RETURN [n IN list WHERE n > 2 | n] AS filteredList
| 过滤列表 |
|---|
|
行数: 1 |
下一个示例展示了如何使用列表推导通过索引映射 LIST。 range() 函数用于生成从 0 到 LIST 的最后一个有效索引的索引,然后将每个索引与其对应的 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
| 映射列表元素 |
|---|
|
行数: 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
| 名称 | 修改后的技能 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
行数: 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 专家 |
|---|
|
行数: 1 |
列表推导可用于在连接 LIST 值时移除任何未知的 null 值。
null 值RETURN [x IN ([1, null, 3] || [null, 5, null]) WHERE x IS NOT NULL] AS listWithoutNull
| 不带 null 的列表 |
|---|
|
行数: 1 |
模式推导
模式推导用于通过匹配图模式并对匹配的元素应用条件来创建新的 LIST 值,返回自定义投影。
[pattern [WHERE predicate] | expression]
下面的查询使用模式推导将 Alice 的所有 employees 的名称提取到 LIST 中,从而检索一个员工姓名列表。
MATCH (alice:Person {name: 'Alice'})
RETURN [(employee:Person)-[:WORKS_FOR]->(alice) | employee.name] AS employees
| 员工 |
|---|
|
行数: 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岁以上员工 |
|---|
|
行数: 1 |
模式推导也可以匹配可变长度模式。但是,模式推导不支持符合 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
| 独特上级技能 |
|---|
|
行数: 1 |