集合运算符¶
合并多个请求时,可以使用集合运算符,包括UNION
、UNION ALL
、INTERSECT
和MINUS
。
所有集合运算符的优先级相同,如果一个 nGQL 语句中有多个集合运算符,NebulaGraph 会从左到右进行计算,除非用括号指定顺序。
Caution
集合运算符前后的查询语句中定义的变量名及顺序必需保持一致,例如RETURN a,b,c UNION RETURN a,b,c
中的a,b,c
的名称及顺序需要保持一致。
UNION、UNION DISTINCT、UNION ALL¶
<left> UNION [DISTINCT | ALL] <right> [ UNION [DISTINCT | ALL] <right> ...]
- 运算符
UNION DISTINCT
(或使用缩写UNION
)返回两个集合 A 和 B 的并集,不包含重复的元素。
- 运算符
UNION ALL
返回两个集合 A 和 B 的并集,包含重复的元素。
left
和right
必须有相同数量的列和数据类型。如果需要转换数据类型,请参见类型转换。
示例¶
# 返回两个查询结果的并集,不包含重复的元素。
nebula> GO FROM "player102" OVER follow YIELD dst(edge) \
UNION \
GO FROM "player100" OVER follow YIELD dst(edge);
+-------------+
| dst(EDGE) |
+-------------+
| "player100" |
| "player101" |
| "player125" |
+-------------+
# 查询 Tag 为 player 的点,根据名称排序后获取前 3 条数据,并与数组合并返回,不包含重复的元素。
nebula> MATCH (v:player) \
WITH v.player.name AS n \
RETURN n ORDER BY n LIMIT 3 \
UNION \
UNWIND ["Tony Parker", "Ben Simmons"] AS n \
RETURN n;
+---------------------+
| n |
+---------------------+
| "Amar'e Stoudemire" |
| "Aron Baynes" |
| "Ben Simmons" |
| "Tony Parker" |
+---------------------+
# 返回两个查询结果的并集,包含重复的元素。
nebula> GO FROM "player102" OVER follow YIELD dst(edge) \
UNION ALL \
GO FROM "player100" OVER follow YIELD dst(edge);
+-------------+
| dst(EDGE) |
+-------------+
| "player100" |
| "player101" |
| "player101" |
| "player125" |
+-------------+
# 查询 Tag 为 player 的点,根据名称排序后获取前 3 条数据,并与数组合并返回,包含重复的元素。
nebula> MATCH (v:player) \
WITH v.player.name AS n \
RETURN n ORDER BY n LIMIT 3 \
UNION ALL \
UNWIND ["Tony Parker", "Ben Simmons"] AS n \
RETURN n;
+---------------------+
| n |
+---------------------+
| "Amar'e Stoudemire" |
| "Aron Baynes" |
| "Ben Simmons" |
| "Tony Parker" |
| "Ben Simmons" |
+---------------------+
# UNION 也可以和 YIELD 语句一起使用,去重时会检查每一行的所有列,每列都相同时才会去重。
nebula> GO FROM "player102" OVER follow \
YIELD dst(edge) AS id, properties(edge).degree AS Degree, properties($$).age AS Age \
UNION /* DISTINCT */ \
GO FROM "player100" OVER follow \
YIELD dst(edge) AS id, properties(edge).degree AS Degree, properties($$).age AS Age;
+-------------+--------+-----+
| id | Degree | Age |
+-------------+--------+-----+
| "player100" | 75 | 42 |
| "player101" | 75 | 36 |
| "player101" | 95 | 36 |
| "player125" | 95 | 41 |
+-------------+--------+-----+
INTERSECT¶
<left> INTERSECT <right>
- 运算符
INTERSECT
返回两个集合 A 和 B 的交集。
left
和right
必须有相同数量的列和数据类型。如果需要转换数据类型,请参见类型转换。
示例¶
# 返回两个查询结果的交集。
nebula> GO FROM "player102" OVER follow \
YIELD dst(edge) AS id, properties(edge).degree AS Degree, properties($$).age AS Age \
INTERSECT \
GO FROM "player100" OVER follow \
YIELD dst(edge) AS id, properties(edge).degree AS Degree, properties($$).age AS Age;
+----+--------+-----+
| id | Degree | Age |
+----+--------+-----+
+----+--------+-----+
# 返回 player102 的邻居和边数据与 player100 的邻居和边数据之间的交集。
nebula> MATCH (v:player)-[e:follow]->(v2) \
WHERE id(v) == "player102" \
RETURN id(v2) As id, e.degree As Degree, v2.player.age AS Age \
INTERSECT \
MATCH (v:player)-[e:follow]->(v2) \
WHERE id(v) == "player100" \
RETURN id(v2) As id, e.degree As Degree, v2.player.age AS Age;
+----+--------+-----+
| id | Degree | Age |
+----+--------+-----+
+----+--------+-----+
# 返回 [1,2] 与 [1,2,3,4] 的交集。
nebula> UNWIND [1,2] AS a RETURN a \
INTERSECT \
UNWIND [1,2,3,4] AS a \
RETURN a;
+---+
| a |
+---+
| 1 |
| 2 |
+---+
MINUS¶
<left> MINUS <right>
运算符MINUS
返回两个集合 A 和 B 的差异,即A-B
。请注意left
和right
的顺序,A-B
表示在集合 A 中,但是不在集合 B 中的元素。
示例¶
# 返回在第一个查询结果中,但是不在第二个查询结果中的元素。
nebula> GO FROM "player100" OVER follow YIELD dst(edge) \
MINUS \
GO FROM "player102" OVER follow YIELD dst(edge);
+-------------+
| dst(EDGE) |
+-------------+
| "player125" |
+-------------+
# 返回在 player102 的邻居中,但不在 player100 的邻居中的元素。
nebula> GO FROM "player102" OVER follow YIELD dst(edge) AS id \
MINUS \
GO FROM "player100" OVER follow YIELD dst(edge) AS id;
+-------------+
| id |
+-------------+
| "player100" |
+-------------+
# 返回在 player102 的邻居中,但不在 player100 的邻居中的元素。
nebula> MATCH (v:player)-[e:follow]->(v2) \
WHERE id(v) =="player102" \
RETURN id(v2) AS id\
MINUS \
MATCH (v:player)-[e:follow]->(v2) \
WHERE id(v) =="player100" \
RETURN id(v2) AS id;
+-------------+
| id |
+-------------+
| "player100" |
+-------------+
# 返回 [1,2,3] 中不与 4 相同的元素。
nebula> UNWIND [1,2,3] AS a RETURN a \
MINUS \
WITH 4 AS a \
RETURN a;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+
集合运算符和管道符的优先级¶
当查询包含集合运算符和管道符(|)时,管道符的优先级高。例如GO FROM 1 UNION GO FROM 2 | GO FROM 3
相当于GO FROM 1 UNION (GO FROM 2 | GO FROM 3)
。
示例¶
nebula> GO FROM "player102" OVER follow \
YIELD dst(edge) AS play_dst \
UNION \
GO FROM "team200" OVER serve REVERSELY \
YIELD src(edge) AS play_src \
| GO FROM $-.play_src OVER follow YIELD dst(edge) AS play_dst;
+-------------+
| play_dst |
+-------------+
| "player100" |
| "player101" |
| "player117" |
| "player105" |
+-------------+
该查询会先执行红框内的语句,然后执行绿框的UNION
操作。
圆括号可以修改执行的优先级,例如:
nebula> (GO FROM "player102" OVER follow \
YIELD dst(edge) AS play_dst \
UNION \
GO FROM "team200" OVER serve REVERSELY \
YIELD src(edge) AS play_dst) \
| GO FROM $-.play_dst OVER follow YIELD dst(edge) AS play_dst;
该查询中,圆括号包裹的部分先执行,即先执行UNION
操作,再将结果结合管道符进行下一步操作。
最后更新:
September 6, 2024