GO¶
GO
从给定起始点开始遍历图。GO
语句采用的路径类型是walk
,即遍历时点和边都可以重复。
openCypher 兼容性¶
本文操作仅适用于原生 nGQL。
语法¶
GO [[<M> TO] <N> {STEP|STEPS} ] FROM <vertex_list>
OVER <edge_type_list> [{REVERSELY | BIDIRECT}]
[ WHERE <conditions> ]
YIELD [DISTINCT] <return_list>
[{ SAMPLE <sample_list> | <limit_by_list_clause> }]
[| GROUP BY {<col_name> | expression> | <position>} YIELD <col_name>]
[| ORDER BY <expression> [{ASC | DESC}]]
[| LIMIT [<offset>,] <number_rows>];
<vertex_list> ::=
<vid> [, <vid> ...]
<edge_type_list> ::=
<edge_type> [, <edge_type> ...]
| *
<return_list> ::=
<col_name> [AS <col_alias>] [, <col_name> [AS <col_alias>] ...]
<N> {STEP|STEPS}
:指定跳数。如果没有指定跳数,默认值N
为1
。如果N
为0
,NebulaGraph 不会检索任何边。
M TO N {STEP|STEPS}
:遍历M~N
跳的边。如果M
为0
,输出结果和M
为1
相同,即GO 0 TO 2
和GO 1 TO 2
是相同的。
<vertex_list>
:用逗号分隔的点 ID 列表,或特殊的引用符$-.id
。详情参见管道符。
<edge_type_list>
:遍历的 Edge type 列表。
REVERSELY | BIDIRECT
:默认情况下检索的是<vertex_list>
的出边(正向),REVERSELY
表示反向,即检索入边;BIDIRECT
为双向,即检索正向和反向,通过返回<edge_type>._type
字段判断方向,其正数为正向,负数为反向。
-
WHERE <conditions>
:指定遍历的过滤条件。用户可以在起始点、目的点和边使用WHERE
子句,还可以结合AND
、OR
、NOT
、XOR
一起使用。详情参见 WHERE。Note
- 遍历多个 Edge type 时,
WHERE
子句有一些限制。例如不支持WHERE edge1.prop1 > edge2.prop2
。 - GO 语句执行时先遍历所有的点,然后再根据过滤器条件进行过滤。
- 遍历多个 Edge type 时,
YIELD [DISTINCT] <return_list>
:定义需要返回的输出。<return_list>
建议使用 Schema 相关函数,当前支持src(edge)
、dst(edge)
、type(edge)
等,暂不支持嵌套函数。详情参见 YIELD。
SAMPLE <sample_list>
:用于在结果集中取样。详情参见 SAMPLE。
<limit_by_list_clause>
:用于在遍历过程中逐步限制输出数量。详情参见 LIMIT。
GROUP BY
:根据指定属性的值将输出分组。详情参见 GROUP BY。分组后需要再次使用YIELD
定义需要返回的输出。
-
ORDER BY
:指定输出结果的排序规则。详情参见 ORDER BY。Note
没有指定排序规则时,输出结果的顺序不是固定的。
LIMIT [<offset>,] <number_rows>]
:限制输出结果的行数。详情参见 LIMIT。
示例¶
# 返回 player102 所属队伍。
nebula> GO FROM "player102" OVER serve YIELD dst(edge);
+-----------+
| dst(EDGE) |
+-----------+
| "team203" |
| "team204" |
+-----------+
# 返回距离 player102 两跳的朋友。
nebula> GO 2 STEPS FROM "player102" OVER follow YIELD dst(edge);
+-------------+
| dst(EDGE) |
+-------------+
| "player101" |
| "player125" |
| "player100" |
| "player102" |
| "player125" |
+-------------+
# 添加过滤条件。
nebula> GO FROM "player100", "player102" OVER serve \
WHERE properties(edge).start_year > 1995 \
YIELD DISTINCT properties($$).name AS team_name, properties(edge).start_year AS start_year, properties($^).name AS player_name;
+-----------------+------------+---------------------+
| team_name | start_year | player_name |
+-----------------+------------+---------------------+
| "Spurs" | 1997 | "Tim Duncan" |
| "Trail Blazers" | 2006 | "LaMarcus Aldridge" |
| "Spurs" | 2015 | "LaMarcus Aldridge" |
+-----------------+------------+---------------------+
# 遍历多个 Edge type。属性没有值时,会显示`NULL`。
nebula> GO FROM "player100" OVER follow, serve \
YIELD properties(edge).degree, properties(edge).start_year;
+-------------------------+-----------------------------+
| properties(EDGE).degree | properties(EDGE).start_year |
+-------------------------+-----------------------------+
| 95 | __NULL__ |
| 95 | __NULL__ |
| __NULL__ | 1997 |
+-------------------------+-----------------------------+
# 返回 player100 入方向的邻居点。
nebula> GO FROM "player100" OVER follow REVERSELY \
YIELD src(edge) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player102" |
...
# 该 MATCH 查询与上一个 GO 查询具有相同的语义。
nebula> MATCH (v)<-[e:follow]- (v2) WHERE id(v) == 'player100' \
RETURN id(v2) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player102" |
...
# 查询 player100 的朋友和朋友所属队伍。
nebula> GO FROM "player100" OVER follow REVERSELY \
YIELD src(edge) AS id | \
GO FROM $-.id OVER serve \
WHERE properties($^).age > 20 \
YIELD properties($^).name AS FriendOf, properties($$).name AS Team;
+---------------------+-----------------+
| FriendOf | Team |
+---------------------+-----------------+
| "Boris Diaw" | "Spurs" |
| "Boris Diaw" | "Jazz" |
| "Boris Diaw" | "Suns" |
...
# 该 MATCH 查询与上一个 GO 查询具有相同的语义。
nebula> MATCH (v)<-[e:follow]- (v2)-[e2:serve]->(v3) \
WHERE id(v) == 'player100' \
RETURN v2.player.name AS FriendOf, v3.team.name AS Team;
+---------------------+-----------------+
| FriendOf | Team |
+---------------------+-----------------+
| "Boris Diaw" | "Spurs" |
| "Boris Diaw" | "Jazz" |
| "Boris Diaw" | "Suns" |
...
# 查询 player100 1~2 跳内的朋友。
nebula> GO 1 TO 2 STEPS FROM "player100" OVER follow \
YIELD dst(edge) AS destination;
+-------------+
| destination |
+-------------+
| "player101" |
| "player125" |
...
# 该 MATCH 查询与上一个 GO 查询具有相同的语义。
nebula> MATCH (v) -[e:follow*1..2]->(v2) \
WHERE id(v) == "player100" \
RETURN id(v2) AS destination;
+-------------+
| destination |
+-------------+
| "player100" |
| "player102" |
...
# 根据年龄分组。
nebula> GO 2 STEPS FROM "player100" OVER follow \
YIELD src(edge) AS src, dst(edge) AS dst, properties($$).age AS age \
| GROUP BY $-.dst \
YIELD $-.dst AS dst, collect_set($-.src) AS src, collect($-.age) AS age;
+-------------+----------------------------+----------+
| dst | src | age |
+-------------+----------------------------+----------+
| "player125" | ["player101"] | [41] |
| "player100" | ["player125", "player101"] | [42, 42] |
| "player102" | ["player101"] | [33] |
+-------------+----------------------------+----------+
# 分组并限制输出结果的行数。
nebula> $a = GO FROM "player100" OVER follow YIELD src(edge) AS src, dst(edge) AS dst; \
GO 2 STEPS FROM $a.dst OVER follow \
YIELD $a.src AS src, $a.dst, src(edge), dst(edge) \
| ORDER BY $-.src | OFFSET 1 LIMIT 2;
+-------------+-------------+-------------+-------------+
| src | $a.dst | src(EDGE) | dst(EDGE) |
+-------------+-------------+-------------+-------------+
| "player100" | "player125" | "player100" | "player101" |
| "player100" | "player101" | "player100" | "player125" |
+-------------+-------------+-------------+-------------+
# 在多个边上通过 IS NOT EMPTY 进行判断。
nebula> GO FROM "player100" OVER follow WHERE properties($$).name IS NOT EMPTY YIELD dst(edge);
+-------------+
| dst(EDGE) |
+-------------+
| "player125" |
| "player101" |
+-------------+
最后更新:
September 4, 2023