WHEREGraph
WHERE
子句可以根据条件过滤输出结果。
WHERE
子句通常用于如下查询:
- nGQL扩展,例如
GO
和LOOKUP
语句。
- openCypher方式,例如
MATCH
和WITH
语句。
openCypher兼容性Graph
- 不支持在
WHERE
子句中使用模式(TODO: planning),例如WHERE (v)-->(v2)
。
- Graph是原生nGQL功能。只支持在nGQL扩展的语句(例如
GO
和LOOKUP
)中使用,因为openCypher中没有rank的概念。
基础用法Graph
Note
下文示例中的$$
、$^
等是引用符号,详情请参见Graph。
用布尔运算符定义条件Graph
在WHERE
子句中使用布尔运算符NOT
、AND
、OR
和XOR
定义条件。关于运算符的优先级,请参见Graph。
nebula> MATCH (v:player) \
WHERE v.name == "Tim Duncan" \
XOR (v.age < 30 AND v.name == "Yao Ming") \
OR NOT (v.name == "Yao Ming" OR v.name == "Tim Duncan") \
RETURN v.name, v.age;
+-------------------------+-------+
| v.name | v.age |
+-------------------------+-------+
| "Marco Belinelli" | 32 |
+-------------------------+-------+
| "Aron Baynes" | 32 |
+-------------------------+-------+
| "LeBron James" | 34 |
+-------------------------+-------+
| "James Harden" | 29 |
+-------------------------+-------+
| "Manu Ginobili" | 41 |
+-------------------------+-------+
...
nebula> GO FROM "player100" \
OVER follow \
WHERE follow.degree > 90 \
OR $$.player.age != 33 \
AND $$.player.name != "Tony Parker";
+-------------+
| follow._dst |
+-------------+
| "player101" |
+-------------+
| "player125" |
+-------------+
过滤属性Graph
在WHERE
子句中使用点或边的属性定义条件。
- 过滤点属性:
nebula> MATCH (v:player)-[e]->(v2) \ WHERE v2.age < 25 \ RETURN v2.name, v2.age; +----------------------+--------+ | v2.name | v2.age | +----------------------+--------+ | "Luka Doncic" | 20 | +----------------------+--------+ | "Kristaps Porzingis" | 23 | +----------------------+--------+ | "Ben Simmons" | 22 | +----------------------+--------+
nebula> GO FROM "player100" \ OVER follow \ WHERE $^.player.age >= 42; +-------------+ | follow._dst | +-------------+ | "player101" | +-------------+ | "player125" | +-------------+
- 过滤边属性:
nebula> MATCH (v:player)-[e]->() \ WHERE e.start_year < 2000 \ RETURN DISTINCT v.name, v.age; +--------------------+-------+ | v.name | v.age | +--------------------+-------+ | "Shaquille O'Neal" | 47 | +--------------------+-------+ | "Steve Nash" | 45 | +--------------------+-------+ | "Ray Allen" | 43 | +--------------------+-------+ | "Grant Hill" | 46 | +--------------------+-------+ | "Tony Parker" | 36 | +--------------------+-------+ ...
nebula> GO FROM "player100" \ OVER follow \ WHERE follow.degree > 90; +-------------+ | follow._dst | +-------------+ | "player101" | +-------------+ | "player125" | +-------------+
过滤动态计算属性Graph
nebula> MATCH (v:player) \
WHERE v[toLower("AGE")] < 21 \
RETURN v.name, v.age;
+---------------+-------+
| v.name | v.age |
+---------------+-------+
| "Luka Doncic" | 20 |
+---------------+-------+
过滤现存属性Graph
nebula> MATCH (v:player) \
WHERE exists(v.age) \
RETURN v.name, v.age;
+-------------------------+-------+
| v.name | v.age |
+-------------------------+-------+
| "Boris Diaw" | 36 |
+-------------------------+-------+
| "DeAndre Jordan" | 30 |
+-------------------------+-------+
过滤rankGraph
在nGQL中,如果多个边拥有相同的起始点、目的点和属性,则它们的唯一区别是rank值。在WHERE
子句中可以使用rank过滤边。
# 创建测试数据。
nebula> CREATE SPACE test;
nebula> USE test;
nebula> CREATE EDGE e1(p1 int);
nebula> CREATE TAG person(p1 int);
nebula> INSERT VERTEX person(p1) VALUES "1":(1);
nebula> INSERT VERTEX person(p1) VALUES "2":(2);
nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@0:(10);
nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@1:(11);
nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@2:(12);
nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@3:(13);
nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@4:(14);
nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@5:(15);
nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@6:(16);
# 通过rank过滤边,查找rank大于2的边。
nebula> GO FROM "1" \
OVER e1 \
WHERE e1._rank>2 \
YIELD e1._src, e1._dst, e1._rank AS Rank, e1.p1 | \
ORDER BY Rank DESC;
====================================
| e1._src | e1._dst | Rank | e1.p1 |
====================================
| 1 | 2 | 6 | 16 |
------------------------------------
| 1 | 2 | 5 | 15 |
------------------------------------
| 1 | 2 | 4 | 14 |
------------------------------------
| 1 | 2 | 3 | 13 |
------------------------------------
过滤字符串Graph
在WHERE
子句中使用STARTS WITH
、ENDS WITH
或CONTAINS
可以匹配字符串的特定部分。匹配时区分大小写。
STARTS WITH
Graph
STARTS WITH
会从字符串的起始位置开始匹配。
# 查询姓名以T开头的player信息。
nebula> MATCH (v:player) \
WHERE v.name STARTS WITH "T" \
RETURN v.name, v.age;
+------------------+-------+
| v.name | v.age |
+------------------+-------+
| "Tracy McGrady" | 39 |
+------------------+-------+
| "Tony Parker" | 36 |
+------------------+-------+
| "Tim Duncan" | 42 |
+------------------+-------+
| "Tiago Splitter" | 34 |
+------------------+-------+
如果使用小写t
(STARTS WITH "t"
),会返回空集,因为数据库中没有以小写t
开头的姓名。
nebula> MATCH (v:player) \
WHERE v.name STARTS WITH "t" \
RETURN v.name, v.age;
Empty set (time spent 5080/6474 us)
ENDS WITH
Graph
ENDS WITH
会从字符串的结束位置开始匹配。
nebula> MATCH (v:player) \
WHERE v.name ENDS WITH "r" \
RETURN v.name, v.age;
+------------------+-------+
| v.name | v.age |
+------------------+-------+
| "Vince Carter" | 42 |
+------------------+-------+
| "Tony Parker" | 36 |
+------------------+-------+
| "Tiago Splitter" | 34 |
+------------------+-------+
CONTAINS
Graph
CONTAINS
会检查关键字是否匹配字符串的某一部分。
nebula> MATCH (v:player) \
WHERE v.name CONTAINS "Pa" \
RETURN v.name, v.age;
+---------------+-------+
| v.name | v.age |
+---------------+-------+
| "Paul George" | 28 |
+---------------+-------+
| "Tony Parker" | 36 |
+---------------+-------+
| "Paul Gasol" | 38 |
+---------------+-------+
| "Chris Paul" | 33 |
+---------------+-------+
结合NOT使用Graph
用户可以结合布尔运算符NOT
一起使用,否定字符串匹配条件。
nebula> MATCH (v:player) \
WHERE NOT v.name ENDS WITH "R" \
RETURN v.name, v.age;
+-------------------------+-------+
| v.name | v.age |
+-------------------------+-------+
| "Rajon Rondo" | 33 |
+-------------------------+-------+
| "Rudy Gay" | 32 |
+-------------------------+-------+
| "Dejounte Murray" | 29 |
+-------------------------+-------+
| "Chris Paul" | 33 |
+-------------------------+-------+
| "Carmelo Anthony" | 34 |
+-------------------------+-------+
...
过滤列表Graph
匹配列表中的值Graph
使用IN
运算符检查某个值是否在指定列表中。
nebula> MATCH (v:player) \
WHERE v.age IN range(20,25) \
RETURN v.name, v.age;
+-------------------------+-------+
| v.name | v.age |
+-------------------------+-------+
| "Ben Simmons" | 22 |
+-------------------------+-------+
| "Kristaps Porzingis" | 23 |
+-------------------------+-------+
| "Luka Doncic" | 20 |
+-------------------------+-------+
| "Kyle Anderson" | 25 |
+-------------------------+-------+
| "Giannis Antetokounmpo" | 24 |
+-------------------------+-------+
| "Joel Embiid" | 25 |
+-------------------------+-------+
结合NOT使用Graph
nebula> MATCH (v:player) \
WHERE v.age NOT IN range(20,25) \
RETURN v.name AS Name, v.age AS Age \
ORDER BY Age;
+---------------------+-----+
| Name | Age |
+---------------------+-----+
| "Kyrie Irving" | 26 |
+---------------------+-----+
| "Cory Joseph" | 27 |
+---------------------+-----+
| "Damian Lillard" | 28 |
+---------------------+-----+
| "Paul George" | 28 |
+---------------------+-----+
| "Ricky Rubio" | 28 |
+---------------------+-----+
...
最后更新: 2021年6月1日