列表表达式
列表表达式允许您在 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
| firstElement | thirdElement | finalElement |
|---|---|---|
|
|
|
行:1 |
||
LIST 中元素的索引可以是参数化的。
{
"myIndex" : 1
}
LIST 元素WITH [1, 2, 3, 4] AS list
RETURN list[$myIndex] AS secondElement
| secondElement |
|---|
|
行:1 |
LIST 中的 LISTWITH [[1, 2], [3, 4], [5, 6]] AS nestedList
RETURN nestedList[1] AS secondList
| secondList |
|---|
|
行:1 |
LIST 中的特定元素WITH [[1, 2], [3, 4], [5, 6]] AS nestedList
RETURN nestedList[1] AS secondList,
nestedList[1][0] AS firstElementOfSecondList
| secondList | 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
| thirdList | secondElementOfThirdList |
|---|---|
|
|
行:1 |
|
用于检查 LIST 成员资格的 IN 运算符可以与 [] 结合使用,以测试元素是否存在于嵌套 LIST 中。
LIST 中的成员资格WITH [[1, 2, 3], [4, 5, 6]] AS nestedList
RETURN 3 IN nestedList[0] AS elementPresent
| elementPresent |
|---|
|
行:1 |
尝试引用 LIST 边界之外的元素将返回 null,尝试从空 LIST 中访问元素也是如此。
LIST 访问WITH [1, 2, 3, 4] AS list, [] AS emptyList
RETURN list[5] AS outOfBound, emptyList[0] AS emptyAccess
| outOfBound | 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
| middleElements | noLowerBound | 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
| finalElementRemoved | finalTwoElementsRemoved | removedFirstThreeAndLast |
|---|---|---|
|
|
|
行:1 |
||
当切片嵌套 LIST 值时,指定切片层级非常重要。以下示例切片外部的 LIST 并返回前两个嵌套的 LIST 值。
LISTWITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
RETURN nestedList[0..2] AS slicedNestedList
| slicedNestedList |
|---|
|
行:1 |
切片内部 LIST 值需要两个 [] 运算符;第一个 [] 用于访问外部 LIST 的元素,第二个用于切片或访问内部 LIST 的元素。
LISTWITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
RETURN nestedList[1][0..2] AS slicedInnerList
| slicedInnerList |
|---|
|
行:1 |
访问特定元素或元素范围还可以与 + 运算符结合使用,以创建一个新 LIST,并将值插入到现有 LIST 值的特定部分中。
LIST 的特定位置WITH [1, 3, 4] AS list
RETURN list[0] + [2] + list[1..] AS newList
| newList |
|---|
|
行:1 |
列表拼接
Cypher 包含两个列表拼接运算符:|| 和 +。|| 符合 GQL 标准,而 + 则不符合。
|| 和 + 进行列表拼接RETURN [1,2] || [3,4] AS list1,
[1,2] + [3,4] AS list2
| list1 | list2 |
|---|---|
|
|
行:1 |
|
LIST 属性MATCH (cecil:Person {name: 'Cecil'}), (cecilia:Person {name: 'Cecilia'})
RETURN cecil.skills || cecilia.skills AS combinedSkills
| combinedSkills |
|---|
|
行:1 |
如果 null 是拼接 LIST 的一部分,则 null 将成为新 LIST 的一部分。
null 的 LISTRETURN [1, 2] || [3, null] AS listWithNull
| listWithNull |
|---|
|
行:1 |
有关在拼接 LIST 值时移除 null 值的信息,请参阅 列表推导。
向列表中添加元素
+ 运算符可以将元素添加到 LIST 值的开头或结尾。使用 || 运算符无法实现此操作。
LIST 的开头和结尾添加元素WITH [1, 2, 3, 4] AS list
RETURN 0 + list AS newBeginning,
list + 5 AS newEnd
| newBeginning | newEnd |
|---|---|
|
|
行: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
| nonNestedAddition | nestedAddition |
|---|---|
|
|
行:1 |
|
LIST 属性的开头添加元素MATCH (cecil:Person {name: 'Cecil'})
SET cecil.skills = "Cypher" + cecil.skills
RETURN cecil.skills AS skillsList
| 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
| filteredList |
|---|
|
行:1 |
下一个示例展示了如何使用索引通过列表推导来映射 LIST。range() 函数用于生成从 0 到 LIST 最后一个有效索引的索引,然后将每个索引与其对应的 LIST 值组合成一个 STRING 值。结果是一个格式为 'index: value' 的 STRING 值的 LIST。
WITH [1,2,3,4] AS list
RETURN [listIndex IN range(0, size(list)-1) | toString(listIndex) || ': ' || toString(list[listIndex])] AS mappedListElements
| mappedListElements |
|---|
|
行:1 |
以下查询遍历每个 Person 节点的 skills 属性,并通过将 STRING " 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
| 名称 (name) | 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
| pythonExperts |
|---|
|
行:1 |
列表推导可用于在拼接 LIST 值时移除任何未知的 null 值。
null 值RETURN [x IN ([1, null, 3] || [null, 5, null]) WHERE x IS NOT NULL] AS listWithoutNull
| listWithoutNull |
|---|
|
行:1 |
模式推导
模式推导用于通过匹配图形模式并将条件应用于匹配的元素来创建新的 LIST 值,并返回自定义投影。
[pattern [WHERE predicate] | expression]
以下查询通过使用模式推导将 employees 的名称提取为 LIST,从而检索为 Alice 工作的员工名单。
MATCH (alice:Person {name: 'Alice'})
RETURN [(employee:Person)-[:WORKS_FOR]->(alice) | employee.name] AS employees
| 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
| employeesAbove30 |
|---|
|
行: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
| distinctSuperiorsSkills |
|---|
|
行:1 |