WHERE

WHERE子句可以根据条件过滤输出结果。

WHERE子句通常用于如下查询:

  • 原生nGQL,例如GOLOOKUP语句。

  • openCypher方式,例如MATCHWITH语句。

openCypher兼容性

  • 不支持在WHERE子句中使用Pattern(TODO: planning),例如WHERE (v)-->(v2)

  • 过滤Rank是原生nGQL功能。如需在openCypher兼容语句中直接获取Rank值,可以使用rank()函数,例如MATCH (:player)-[e:follow]->() RETURN rank(e);

基础用法

Note

下文示例中的$$$^等是引用符号,详情请参见引用符

用布尔运算符定义条件

WHERE子句中使用布尔运算符NOTANDORXOR定义条件。关于运算符的优先级,请参见运算符优先级

  1. nebula> MATCH (v:player) \
  2. WHERE v.name == "Tim Duncan" \
  3. XOR (v.age < 30 AND v.name == "Yao Ming") \
  4. OR NOT (v.name == "Yao Ming" OR v.name == "Tim Duncan") \
  5. RETURN v.name, v.age;
  6. +-------------------------+-------+
  7. | v.name | v.age |
  8. +-------------------------+-------+
  9. | "Marco Belinelli" | 32 |
  10. | "Aron Baynes" | 32 |
  11. | "LeBron James" | 34 |
  12. | "James Harden" | 29 |
  13. | "Manu Ginobili" | 41 |
  14. +-------------------------+-------+
  15. ...
  1. nebula> GO FROM "player100" \
  2. OVER follow \
  3. WHERE properties(edge).degree > 90 \
  4. OR properties($$).age != 33 \
  5. AND properties($$).name != "Tony Parker" \
  6. YIELD properties($$);
  7. +----------------------------------+
  8. | properties($$) |
  9. +----------------------------------+
  10. | {age: 41, name: "Manu Ginobili"} |
  11. +----------------------------------+

过滤属性

WHERE子句中使用点或边的属性定义条件。

  • 过滤点属性:

    1. nebula> MATCH (v:player)-[e]->(v2) \
    2. WHERE v2.age < 25 \
    3. RETURN v2.name, v2.age;
    4. +----------------------+--------+
    5. | v2.name | v2.age |
    6. +----------------------+--------+
    7. | "Luka Doncic" | 20 |
    8. | "Kristaps Porzingis" | 23 |
    9. | "Ben Simmons" | 22 |
    10. +----------------------+--------+
    1. nebula> GO FROM "player100" \
    2. OVER follow \
    3. WHERE $^.player.age >= 42;
    4. +-------------+
    5. | follow._dst |
    6. +-------------+
    7. | "player101" |
    8. | "player125" |
    9. +-------------+
  • 过滤边属性:

    1. nebula> MATCH (v:player)-[e]->() \
    2. WHERE e.start_year < 2000 \
    3. RETURN DISTINCT v.name, v.age;
    4. +--------------------+-------+
    5. | v.name | v.age |
    6. +--------------------+-------+
    7. | "Shaquille O'Neal" | 47 |
    8. | "Steve Nash" | 45 |
    9. | "Ray Allen" | 43 |
    10. | "Grant Hill" | 46 |
    11. | "Tony Parker" | 36 |
    12. +--------------------+-------+
    13. ...
    1. nebula> GO FROM "player100" \
    2. OVER follow \
    3. WHERE follow.degree > 90;
    4. +-------------+
    5. | follow._dst |
    6. +-------------+
    7. | "player101" |
    8. | "player125" |
    9. +-------------+

过滤动态计算属性

  1. nebula> MATCH (v:player) \
  2. WHERE v[toLower("AGE")] < 21 \
  3. RETURN v.name, v.age;
  4. +---------------+-------+
  5. | v.name | v.age |
  6. +---------------+-------+
  7. | "Luka Doncic" | 20 |
  8. +---------------+-------+

过滤现存属性

  1. nebula> MATCH (v:player) \
  2. WHERE exists(v.age) \
  3. RETURN v.name, v.age;
  4. +-------------------------+-------+
  5. | v.name | v.age |
  6. +-------------------------+-------+
  7. | "Boris Diaw" | 36 |
  8. | "DeAndre Jordan" | 30 |
  9. +-------------------------+-------+
  10. ...

过滤rank

在nGQL中,如果多个边拥有相同的起始点、目的点和属性,则它们的唯一区别是rank值。在WHERE子句中可以使用rank过滤边。

  1. # 创建测试数据。
  2. nebula> CREATE SPACE test (vid_type=FIXED_STRING(30));
  3. nebula> USE test;
  4. nebula> CREATE EDGE e1(p1 int);
  5. nebula> CREATE TAG person(p1 int);
  6. nebula> INSERT VERTEX person(p1) VALUES "1":(1);
  7. nebula> INSERT VERTEX person(p1) VALUES "2":(2);
  8. nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@0:(10);
  9. nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@1:(11);
  10. nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@2:(12);
  11. nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@3:(13);
  12. nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@4:(14);
  13. nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@5:(15);
  14. nebula> INSERT EDGE e1(p1) VALUES "1"->"2"@6:(16);
  15. # 通过rank过滤边,查找rank大于2的边。
  16. nebula> GO FROM "1" \
  17. OVER e1 \
  18. WHERE rank(edge) > 2 \
  19. YIELD src(edge), dst(edge), rank(edge) AS Rank, properties(edge).p1 | \
  20. ORDER BY $-.Rank DESC;
  21. +-----------+-----------+------+---------------------+
  22. | src(EDGE) | dst(EDGE) | Rank | properties(EDGE).p1 |
  23. +-----------+-----------+------+---------------------+
  24. | "1" | "2" | 6 | 16 |
  25. | "1" | "2" | 5 | 15 |
  26. | "1" | "2" | 4 | 14 |
  27. | "1" | "2" | 3 | 13 |
  28. +-----------+-----------+------+---------------------+

过滤字符串

WHERE子句中使用STARTS WITHENDS WITHCONTAINS可以匹配字符串的特定部分。匹配时区分大小写。

STARTS WITH

STARTS WITH会从字符串的起始位置开始匹配。

  1. # 查询姓名以T开头的player信息。
  2. nebula> MATCH (v:player) \
  3. WHERE v.name STARTS WITH "T" \
  4. RETURN v.name, v.age;
  5. +------------------+-------+
  6. | v.name | v.age |
  7. +------------------+-------+
  8. | "Tracy McGrady" | 39 |
  9. | "Tony Parker" | 36 |
  10. | "Tim Duncan" | 42 |
  11. | "Tiago Splitter" | 34 |
  12. +------------------+-------+

如果使用小写tSTARTS WITH "t"),会返回空集,因为数据库中没有以小写t开头的姓名。

  1. nebula> MATCH (v:player) \
  2. WHERE v.name STARTS WITH "t" \
  3. RETURN v.name, v.age;
  4. Empty set (time spent 5080/6474 us)

ENDS WITH

ENDS WITH会从字符串的结束位置开始匹配。

  1. nebula> MATCH (v:player) \
  2. WHERE v.name ENDS WITH "r" \
  3. RETURN v.name, v.age;
  4. +------------------+-------+
  5. | v.name | v.age |
  6. +------------------+-------+
  7. | "Vince Carter" | 42 |
  8. | "Tony Parker" | 36 |
  9. | "Tiago Splitter" | 34 |
  10. +------------------+-------+

CONTAINS

CONTAINS会检查关键字是否匹配字符串的某一部分。

  1. nebula> MATCH (v:player) \
  2. WHERE v.name CONTAINS "Pa" \
  3. RETURN v.name, v.age;
  4. +---------------+-------+
  5. | v.name | v.age |
  6. +---------------+-------+
  7. | "Paul George" | 28 |
  8. | "Tony Parker" | 36 |
  9. | "Paul Gasol" | 38 |
  10. | "Chris Paul" | 33 |
  11. +---------------+-------+

结合NOT使用

用户可以结合布尔运算符NOT一起使用,否定字符串匹配条件。

  1. nebula> MATCH (v:player) \
  2. WHERE NOT v.name ENDS WITH "R" \
  3. RETURN v.name, v.age;
  4. +-------------------------+-------+
  5. | v.name | v.age |
  6. +-------------------------+-------+
  7. | "Rajon Rondo" | 33 |
  8. | "Rudy Gay" | 32 |
  9. | "Dejounte Murray" | 29 |
  10. | "Chris Paul" | 33 |
  11. | "Carmelo Anthony" | 34 |
  12. +-------------------------+-------+
  13. ...

过滤列表

匹配列表中的值

使用IN运算符检查某个值是否在指定列表中。

  1. nebula> MATCH (v:player) \
  2. WHERE v.age IN range(20,25) \
  3. RETURN v.name, v.age;
  4. +-------------------------+-------+
  5. | v.name | v.age |
  6. +-------------------------+-------+
  7. | "Ben Simmons" | 22 |
  8. | "Kristaps Porzingis" | 23 |
  9. | "Luka Doncic" | 20 |
  10. | "Kyle Anderson" | 25 |
  11. | "Giannis Antetokounmpo" | 24 |
  12. | "Joel Embiid" | 25 |
  13. +-------------------------+-------+
  14. nebula> LOOKUP ON player \
  15. WHERE player.age IN [25,28] \
  16. YIELD properties(vertex).name, properties(vertex).age;
  17. +-------------+-------------------------+------------------------+
  18. | VertexID | properties(VERTEX).name | properties(VERTEX).age |
  19. +-------------+-------------------------+------------------------+
  20. | "player106" | "Kyle Anderson" | 25 |
  21. | "player135" | "Damian Lillard" | 28 |
  22. | "player130" | "Joel Embiid" | 25 |
  23. | "player131" | "Paul George" | 28 |
  24. | "player123" | "Ricky Rubio" | 28 |
  25. +-------------+-------------------------+------------------------+

结合NOT使用

  1. nebula> MATCH (v:player) \
  2. WHERE v.age NOT IN range(20,25) \
  3. RETURN v.name AS Name, v.age AS Age \
  4. ORDER BY Age;
  5. +---------------------+-----+
  6. | Name | Age |
  7. +---------------------+-----+
  8. | "Kyrie Irving" | 26 |
  9. | "Cory Joseph" | 27 |
  10. | "Damian Lillard" | 28 |
  11. | "Paul George" | 28 |
  12. | "Ricky Rubio" | 28 |
  13. +---------------------+-----+
  14. ...

最后更新: November 1, 2021