列表表达式
列表表达式允许您在 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
中的 LIST
WITH [[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
值。
LIST
WITH [[1, 2, 3], [4, 5, 6], [7, 8, 9]] AS nestedList
RETURN nestedList[0..2] AS slicedNestedList
切片嵌套列表 |
---|
|
行数: 1 |
切片内部 LIST
值需要两个 []
运算符;第一个 []
访问外部 LIST
中的元素,而第二个则切片或访问内部 LIST
中的元素。
LIST
WITH [[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
的 LIST
RETURN [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
值添加到嵌套 LIST
WITH [[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 |