UNWIND(展开)

简介

Cypher 中的 UNWIND 子句用于将列表展开为一系列单独的元素。它将列表值转换为行。对于列表中的每个元素,UNWIND 创建一个新行,变量绑定到该列表元素。如果表达式求值为 null,或空列表,UNWIND 将分别产生一个值为 null 的单行,或根本不产生行,具体取决于数据库实现。在 AGE 中,当表达式为 null 时,UNWIND 将产生一个值为 null 的单行;当列表为空时,不产生任何行。

UNWIND 在处理节点或关系的列表属性,或需要在查询中遍历值集合时特别有用。

示例

数据准备

以下部分示例将使用此参考数据:

SELECT * FROM cypher('cypher_unwind', $$
    CREATE (n {name: 'node1', a: [1, 2, 3]}),
           (m {name: 'node2', a: [4, 5, 6]}),
           (o {name: 'node3', a: [7, 8, 9]}),
           (n)-[:KNOWS]->(m),
           (m)-[:KNOWS]->(o)
$$) as (i agtype);

基本 UNWIND:整数列表

此示例演示了 UNWIND 最基本的用法,将整数字面量列表展开为单独的行。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    UNWIND [1, 2, 3] AS i
    RETURN i
$$) as (i agtype);

输出

i
---
1
2
3
(3 rows)

UNWIND 与节点属性

此示例展示如何使用 UNWIND 处理节点的列表属性,使用参考数据。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    MATCH (n)
    WITH n.a AS a
    UNWIND a AS i
    RETURN *
$$) as (i agtype, j agtype);

输出

i | j
-----------|---
[1, 2, 3] | 1
[1, 2, 3] | 2
[1, 2, 3] | 3
[4, 5, 6] | 4
[4, 5, 6] | 5
[4, 5, 6] | 6
[7, 8, 9] | 7
[7, 8, 9] | 8
[7, 8, 9] | 9
(9 rows)

嵌套 UNWIND

UNWIND 可以嵌套使用以展平嵌套列表。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    WITH [[1, 2], [3, 4], 5] AS nested
    UNWIND nested AS x
    UNWIND x AS y
    RETURN y
$$) as (i agtype);

输出

i
---
1
2
3
4
5
(5 rows)

UNWIND 与路径函数:nodes()

UNWIND 可以与路径函数(如 nodes())一起使用来处理路径中的顶点。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    MATCH p=(n)-[:KNOWS]->(m)
    UNWIND nodes(p) as node
    RETURN node
$$) as (i agtype);

输出

i
-----------------------------------------------------------------------------------------------
{"id": 281474976710657, "label": "", "properties": {"a": [1, 2, 3], "name": "node1"}}::vertex
{"id": 281474976710658, "label": "", "properties": {"a": [4, 5, 6], "name": "node2"}}::vertex
{"id": 281474976710658, "label": "", "properties": {"a": [4, 5, 6], "name": "node2"}}::vertex
{"id": 281474976710659, "label": "", "properties": {"a": [7, 8, 9], "name": "node3"}}::vertex
(4 rows)

UNWIND 与路径函数:relationships()

类似地,UNWIND 可以与 relationships() 一起使用来处理路径中的关系。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    MATCH p=(n)-[:KNOWS]->(m)
    UNWIND relationships(p) as relation
    RETURN relation
$$) as (i agtype);

输出

i
---------------------------------------------------------------------------------------------------------------------------
{"id": 844424930131969, "label": "KNOWS", "end_id": 281474976710658, "start_id": 281474976710657, "properties": {}}::edge
{"id": 844424930131970, "label": "KNOWS", "end_id": 281474976710659, "start_id": 281474976710658, "properties": {}}::edge
(2 rows)

UNWIND 与路径函数:relationships()paths

此示例演示从路径中展开关系,其中路径本身也被展开。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    MATCH p=({name:'node1'})-[e:KNOWS*]->({name:'node3'})
    UNWIND [p] as path
    UNWIND relationships(path) as edge
    RETURN edge
$$) as (i agtype);

输出

i
---------------------------------------------------------------------------------------------------------------------------
 {"id": 844424930131969, "label": "KNOWS", "end_id": 281474976710658, "start_id": 281474976710657, "properties": {}}::edge
 {"id": 844424930131970, "label": "KNOWS", "end_id": 281474976710659, "start_id": 281474976710658, "properties": {}}::edge
(2 rows)

UNWIND 在 SET 子句中(暂不支持)

UNWIND 可以与 SET 子句结合使用,根据展开的值更新属性。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    MATCH p=(n)-[:KNOWS]->(m)
    UNWIND nodes(p) as node
    SET node.type = 'vertex'
$$) as (i agtype);

输出

i
---
(0 rows)

UNWIND 与 NULL

此示例展示 UNWIND 如何处理 NULL 值。在处理可选的列表属性或表达式可能求值为 NULL 的情况时,理解此行为非常重要。

SQL 查询

SELECT * FROM cypher('cypher_unwind', $$
    UNWIND NULL as i
    RETURN i
$$) as (i agtype);

输出

i
---

(1 row)