跳转至

列表

列表(List)是复合数据类型,一个列表是一组元素的序列,可以通过元素在序列中的位置访问列表中的元素。

列表用左方括号([)和右方括号(])包裹多个元素,各个元素之间用英文逗号(,)隔开。元素前后的空格在列表中被忽略,因此可以使用换行符、制表符和空格调整格式。

OpenCypher 兼容性

复合数据类型(例如 List、Set、Map)不能存储为点或边的属性。

列表操作

对列表进行操作可以使用预设的列表函数,也可以使用下标表达式过滤列表内的元素。

下标表达式语法

[M]
[M..N]
[M..]
[..N]

nGQL 的下标支持从前往后查询,从 0 开始,0 表示第一个元素,1 表示第二个元素,以此类推;也支持从后往前查询,从-1 开始,-1 表示最后一个元素,-2 表示倒数第二个元素,以此类推。

  • [M]:表示下标为 M 的元素。
  • [M..N]:表示M ≤ 下标 < N的元素。N为 0 时,返回为空。
  • [M..]:表示M ≤ 下标的元素。
  • [..N]:表示下标 < N的元素。N为 0 时,返回为空。

Note

  • 越界的下标返回为空,未越界的可以正常返回。
  • MN时,返回为空。
  • 查询单个元素时,如果M为 null,返回报错BAD_TYPE;范围查询时,MN为 null,返回为null

示例

# 返回列表 [1,2,3]
nebula> RETURN list[1, 2, 3] AS a;
+-----------+
| a         |
+-----------+
| [1, 2, 3] |
+-----------+

# 返回列表 [1,2,3,4,5] 中位置下标为 3 的元素。列表的位置下标是从 0 开始,因此返回的元素为 4。
nebula> RETURN range(1,5)[3];
+---------------+
| range(1,5)[3] |
+---------------+
| 4             |
+---------------+

# 返回列表 [1,2,3,4,5] 中位置下标为-2 的元素。列表的最后一个元素的位置下标是-1,因此-2 是指倒数第二个元素,即 4。
nebula> RETURN range(1,5)[-2];
+------------------+
| range(1,5)[-(2)] |
+------------------+
| 4                |
+------------------+

# 返回列表 [1,2,3,4,5] 中下标位置从 0 到 3(不包括 3)的元素。
nebula> RETURN range(1,5)[0..3];
+------------------+
| range(1,5)[0..3] |
+------------------+
| [1, 2, 3]        |
+------------------+

# 返回列表 [1,2,3,4,5] 中位置下标大于 2 的元素。
nebula> RETURN range(1,5)[3..] AS a;
+--------+
| a      |
+--------+
| [4, 5] |
+--------+

# 返回列表内下标小于 3 的元素。
nebula> WITH list[1, 2, 3, 4, 5] AS a \
        RETURN a[..3] AS r;
+-----------+
| r         |
+-----------+
| [1, 2, 3] |
+-----------+

# 筛选列表 [1,2,3,4,5] 中大于 2 的元素,将这些元素分别做运算并返回。
nebula> RETURN [n IN range(1,5) WHERE n > 2 | n + 10] AS a;
+--------------+
| a            |
+--------------+
| [13, 14, 15] |
+--------------+

# 返回列表内第一个至倒数第二个(包括)的元素。
nebula> YIELD list[1, 2, 3][0..-1] AS a;
+--------+
| a      |
+--------+
| [1, 2] |
+--------+

# 返回列表内倒数第三个至倒数第一个(不包括)的元素。
nebula> YIELD list[1, 2, 3, 4, 5][-3..-1] AS a;
+--------+
| a      |
+--------+
| [3, 4] |
+--------+

# 设置变量,返回列表内下标为 1、2 的元素。
nebula> $var = YIELD 1 AS f, 3 AS t; \
        YIELD list[1, 2, 3][$var.f..$var.t] AS a;
+--------+
| a      |
+--------+
| [2, 3] |
+--------+

# 越界的下标返回为空,未越界的可以正常返回。
nebula> RETURN list[1, 2, 3, 4, 5] [0..10] AS a;
+-----------------+
| a               |
+-----------------+
| [1, 2, 3, 4, 5] |
+-----------------+

nebula> RETURN list[1, 2, 3] [-5..5] AS a;
+-----------+
| a         |
+-----------+
| [1, 2, 3] |
+-----------+

# [0..0] 时返回为空。
nebula> RETURN list[1, 2, 3, 4, 5] [0..0] AS a;
+----+
| a  |
+----+
| [] |
+----+

# M ≥ N 时,返回为空。
nebula> RETURN list[1, 2, 3, 4, 5] [3..1] AS a;
+----+
| a  |
+----+
| [] |
+----+

# 范围查询时,下标有 null 时,返回为 null。
nebula> WITH list[1,2,3] AS a \
        RETURN a[0..null] as r;
+----------+
| r        |
+----------+
| __NULL__ |
+----------+

# 将列表 [1,2,3,4,5] 中的元素分别做运算,然后将列表去掉表头并返回。
nebula> RETURN tail([n IN range(1, 5) | 2 * n - 10]) AS a;
+-----------------+
| a               |
+-----------------+
| [-6, -4, -2, 0] |
+-----------------+

# 将列表 [1,2,3] 中的元素判断为真,然后返回。
nebula> RETURN [n IN range(1, 3) WHERE true | n] AS r;
+-----------+
| r         |
+-----------+
| [1, 2, 3] |
+-----------+

# 返回列表 [1,2,3] 的长度。
nebula> RETURN size(list[1,2,3]);
+---------------+
| size([1,2,3]) |
+---------------+
| 3             |
+---------------+

# 将列表 [92,90] 中的元素做运算,然后在 where 子句中进行条件判断。
nebula> GO FROM "player100" OVER follow WHERE properties(edge).degree NOT IN [x IN [92, 90] | x + $$.player.age] \
        YIELD dst(edge) AS id, properties(edge).degree AS degree;
+-------------+--------+
| id          | degree |
+-------------+--------+
| "player101" | 95     |
| "player102" | 90     |
+-------------+--------+

# 将 MATCH 语句的查询结果作为列表中的元素进行运算并返回。
nebula> MATCH p = (n:player{name:"Tim Duncan"})-[:follow]->(m) \
        RETURN [n IN nodes(p) | n.age + 100] AS r;
+------------+
| r          |
+------------+
| [142, 136] |
| [142, 133] |
+------------+

OpenCypher 兼容性

  • 在 openCypher 中,查询越界元素时返回null,而在 nGQL 中,查询单个越界元素时返回OUT_OF_RANGE
    nebula> RETURN range(0,5)[-12];
    +-------------------+
    | range(0,5)[-(12)] |
    +-------------------+
    | OUT_OF_RANGE      |
    +-------------------+
    
  • 复合数据类型(例如 set、map、list)不能存储为点或边的属性。

    • 建议修改图建模方式:将复合数据类型建模为点的邻边,而不是该点的自身属性,每条邻边可以动态增删,并且可以设置邻边的 Rank 值来控制邻边的顺序。
  • List 中不支持 pattern,例如 [(src)-[]->(m) | m.name]

最后更新: February 23, 2023