LOOKUP

LOOKUP根据索引遍历数据。您可以使用LOOKUP实现如下功能:

  • 根据WHERE子句搜索特定数据。

  • 通过标签列出点: 检索指定标签的所有点ID。

  • 通过边类型列出边:检索指定边类型的所有边的起始点、目的点和rank。

  • 计数指定标签的点或指定边类型的边。

openCypher兼容性

本文操作仅适用于nGQL扩展。

前提条件

请确保LOOKUP语句有至少一个索引可用。如果您需要创建索引,但是已经有相关的点、边或属性,您必须在创建索引后重建索引,索引才能生效。

警告:正确使用索引可以加快查询速度,但是索引会导致写性能大幅降低(降低90%甚至更多)。请不要随意在生产环境中使用索引,除非您很清楚使用索引对业务的影响。

语法

  1. LOOKUP ON {<vertex_tag> | <edge_type>} [WHERE <expression> [AND <expression> ...]] [YIELD <return_list>];
  2. <return_list>
  3. <prop_name> [AS <col_alias>] [, <prop_name> [AS <prop_alias>] ...];
  • WHERE <expression>:指定遍历的过滤条件,还可以结合AND、OR一起使用。详情请参见WHERE

  • YIELD <return_list>:指定要返回的结果和格式.

  • 如果只有WHERE子句,没有YIELD子句:

    • LOOKUP标签时,返回点ID。
    • LOOKUP边类型时,返回起始点ID、目的点ID和rank。

WHERE语句限制

LOOKUP语句中使用WHERE子句,不支持如下操作:

  • $-$^
  • 在关系表达式中,不支持运算符两边都有字段名,例如tagName.prop1> tagName.prop2
  • 不支持运算表达式和函数表达式中嵌套AliasProp表达式。
  • 字符串类型索引不支持范围扫描。
  • 不支持ORXOR运算符。

检索点

返回标签为playernameTony Parker的点。

  1. nebula> CREATE TAG INDEX index_player ON player(name(30), age);
  2. nebula> REBUILD TAG INDEX index_player;
  3. +------------+
  4. | New Job Id |
  5. +------------+
  6. | 15 |
  7. +------------+
  8. nebula> LOOKUP ON player WHERE player.name == "Tony Parker";
  9. ============
  10. | VertexID |
  11. ============
  12. | 101 |
  13. ------------
  14. nebula> LOOKUP ON player WHERE player.name == "Tony Parker" \
  15. YIELD player.name, player.age;
  16. =======================================
  17. | VertexID | player.name | player.age |
  18. =======================================
  19. | 101 | Tony Parker | 36 |
  20. ---------------------------------------
  21. nebula> LOOKUP ON player WHERE player.name == "Kobe Bryant" YIELD player.name AS name \
  22. | GO FROM $-.VertexID OVER serve \
  23. YIELD $-.name, serve.start_year, serve.end_year, $$.team.name;
  24. ==================================================================
  25. | $-.name | serve.start_year | serve.end_year | $$.team.name |
  26. ==================================================================
  27. | Kobe Bryant | 1996 | 2016 | Lakers |
  28. ------------------------------------------------------------------

检索边

返回边类型为followdegree90的边。

  1. nebula> CREATE EDGE INDEX index_follow ON follow(degree);
  2. nebula> REBUILD EDGE INDEX index_follow;
  3. +------------+
  4. | New Job Id |
  5. +------------+
  6. | 62 |
  7. +------------+
  8. nebula> LOOKUP ON follow WHERE follow.degree == 90;
  9. =============================
  10. | SrcVID | DstVID | Ranking |
  11. =============================
  12. | 100 | 106 | 0 |
  13. -----------------------------
  14. nebula> LOOKUP ON follow WHERE follow.degree == 90 YIELD follow.degree;
  15. =============================================
  16. | SrcVID | DstVID | Ranking | follow.degree |
  17. =============================================
  18. | 100 | 106 | 0 | 90 |
  19. ---------------------------------------------
  20. nebula> LOOKUP ON follow WHERE follow.degree == 60 YIELD follow.degree AS Degree \
  21. | GO FROM $-.DstVID OVER serve \
  22. YIELD $-.DstVID, serve.start_year, serve.end_year, $$.team.name;
  23. ================================================================
  24. | $-.DstVID | serve.start_year | serve.end_year | $$.team.name |
  25. ================================================================
  26. | 105 | 2010 | 2018 | Spurs |
  27. ----------------------------------------------------------------
  28. | 105 | 2009 | 2010 | Cavaliers |
  29. ----------------------------------------------------------------
  30. | 105 | 2018 | 2019 | Raptors |
  31. ----------------------------------------------------------------

通过标签列出点/通过边类型列出边

如果需要通过标签列出点,或通过边类型列出边,则标签、边类型或属性上必须有至少一个索引。

例如一个标签player有两个属性nameage,为了遍历所有包含标签player的点ID,标签player、属性name或属性age中必须有一个已经创建索引。

  • 检索所有标记为player的点ID。

    1. nebula> CREATE TAG player(name string,age int);
    2. nebula> CREATE TAG INDEX player_index on player();
    3. nebula> REBUILD TAG INDEX player_index;
    4. +------------+
    5. | New Job Id |
    6. +------------+
    7. | 66 |
    8. +------------+
    9. nebula> INSERT VERTEX player(name,age) VALUES "player100":("Tim Duncan", 42), "player101":("Tony Parker", 36);
    10. nebula> LOOKUP ON player;
    11. +-------------+
    12. | _vid |
    13. +-------------+
    14. | "player100" |
    15. +-------------+
    16. | "player101" |
    17. +-------------+
  • 检索边类型为like的所有边的信息。

    1. nebula)> CREATE EDGE like(likeness int);
    2. nebula)> CREATE EDGE INDEX like_index on like();
    3. nebula> REBUILD EDGE INDEX like_index;
    4. +------------+
    5. | New Job Id |
    6. +------------+
    7. | 88 |
    8. +------------+
    9. nebula)> INSERT EDGE like(likeness) values "player100"->"player101":(95);
    10. nebula)> LOOKUP ON like;
    11. +-------------+----------+-------------+
    12. | _src | _ranking | _dst |
    13. +-------------+----------+-------------+
    14. | "player100" | 0 | "player101" |
    15. +-------------+----------+-------------+

计数点或边

计数标签为player的点和边类型为like的边。

  1. nebula> LOOKUP ON player | YIELD COUNT(*) AS Player_Number;
  2. +---------------+
  3. | Player_Number |
  4. +---------------+
  5. | 2 |
  6. +---------------+
  7. nebula> LOOKUP ON like | YIELD COUNT(*) AS Like_Number;
  8. +-------------+
  9. | Like_Number |
  10. +-------------+
  11. | 1 |
  12. +-------------+

FAQ

错误码411

  1. [ERROR (-8)]: Unknown error(411):

错误码411表示WHERE过滤时没有有效的索引。Nebula Graph的索引使用的是最左匹配原则,即从最左边的为起点任何连续的索引都能匹配上。例如:

  1. # 为标签t的前三个属性创建索引。
  2. nebula> CREATE TAG INDEX example_index ON TAG t(p1, p2, p3);
  3. # 无法匹配索引,因为不是从p1开始。
  4. nebula> LOOKUP ON t WHERE p2 == 1 and p3 == 1;
  5. # 可以匹配索引。
  6. nebula> LOOKUP ON t WHERE p1 == 1;
  7. # 可以匹配索引,因为p1和p2是连续的。
  8. nebula> LOOKUP ON t WHERE p1 == 1 and p2 == 1;
  9. # 可以匹配索引,因为p1、p2、p3是连续的。
  10. nebula> LOOKUP ON t WHERE p1 == 1 and p2 == 1 and p3 == 1;

没有找到有效索引

  1. No valid index found

如果您的查询过滤器包含字符串类型的字段,Nebula Graph会选择匹配所有字段的索引。例如:

  1. nebula> CREATE TAG t1 (c1 string, c2 int);
  2. nebula> CREATE TAG INDEX i1 ON t1 (c1, c2);
  3. # 索引i1无效。
  4. nebula> LOOKUP ON t1 WHERE t1.c1 == "a";
  5. # 索引i1有效。
  6. nebula> LOOKUP ON t1 WHERE t1.c1 == "a" and t1.c2 == 1;