LOOKUP
LOOKUP
根据索引遍历数据。您可以使用LOOKUP
实现如下功能:
根据
WHERE
子句搜索特定数据。通过标签列出点: 检索指定标签的所有点ID。
通过边类型列出边:检索指定边类型的所有边的起始点、目的点和rank。
计数指定标签的点或指定边类型的边。
openCypher兼容性
本文操作仅适用于nGQL扩展。
前提条件
请确保LOOKUP
语句有至少一个索引可用。如果您需要创建索引,但是已经有相关的点、边或属性,您必须在创建索引后重建索引,索引才能生效。
警告:正确使用索引可以加快查询速度,但是索引会导致写性能大幅降低(降低90%甚至更多)。请不要随意在生产环境中使用索引,除非您很清楚使用索引对业务的影响。
语法
LOOKUP ON {<vertex_tag> | <edge_type>} [WHERE <expression> [AND <expression> ...]] [YIELD <return_list>];
<return_list>
<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表达式。
- 字符串类型索引不支持范围扫描。
- 不支持
OR
和XOR
运算符。
检索点
返回标签为player
且name
为Tony Parker
的点。
nebula> CREATE TAG INDEX index_player ON player(name(30), age);
nebula> REBUILD TAG INDEX index_player;
+------------+
| New Job Id |
+------------+
| 15 |
+------------+
nebula> LOOKUP ON player WHERE player.name == "Tony Parker";
============
| VertexID |
============
| 101 |
------------
nebula> LOOKUP ON player WHERE player.name == "Tony Parker" \
YIELD player.name, player.age;
=======================================
| VertexID | player.name | player.age |
=======================================
| 101 | Tony Parker | 36 |
---------------------------------------
nebula> LOOKUP ON player WHERE player.name == "Kobe Bryant" YIELD player.name AS name \
| GO FROM $-.VertexID OVER serve \
YIELD $-.name, serve.start_year, serve.end_year, $$.team.name;
==================================================================
| $-.name | serve.start_year | serve.end_year | $$.team.name |
==================================================================
| Kobe Bryant | 1996 | 2016 | Lakers |
------------------------------------------------------------------
检索边
返回边类型为follow
且degree
为90
的边。
nebula> CREATE EDGE INDEX index_follow ON follow(degree);
nebula> REBUILD EDGE INDEX index_follow;
+------------+
| New Job Id |
+------------+
| 62 |
+------------+
nebula> LOOKUP ON follow WHERE follow.degree == 90;
=============================
| SrcVID | DstVID | Ranking |
=============================
| 100 | 106 | 0 |
-----------------------------
nebula> LOOKUP ON follow WHERE follow.degree == 90 YIELD follow.degree;
=============================================
| SrcVID | DstVID | Ranking | follow.degree |
=============================================
| 100 | 106 | 0 | 90 |
---------------------------------------------
nebula> LOOKUP ON follow WHERE follow.degree == 60 YIELD follow.degree AS Degree \
| GO FROM $-.DstVID OVER serve \
YIELD $-.DstVID, serve.start_year, serve.end_year, $$.team.name;
================================================================
| $-.DstVID | serve.start_year | serve.end_year | $$.team.name |
================================================================
| 105 | 2010 | 2018 | Spurs |
----------------------------------------------------------------
| 105 | 2009 | 2010 | Cavaliers |
----------------------------------------------------------------
| 105 | 2018 | 2019 | Raptors |
----------------------------------------------------------------
通过标签列出点/通过边类型列出边
如果需要通过标签列出点,或通过边类型列出边,则标签、边类型或属性上必须有至少一个索引。
例如一个标签player
有两个属性name
和age
,为了遍历所有包含标签player
的点ID,标签player
、属性name
或属性age
中必须有一个已经创建索引。
检索所有标记为
player
的点ID。nebula> CREATE TAG player(name string,age int);
nebula> CREATE TAG INDEX player_index on player();
nebula> REBUILD TAG INDEX player_index;
+------------+
| New Job Id |
+------------+
| 66 |
+------------+
nebula> INSERT VERTEX player(name,age) VALUES "player100":("Tim Duncan", 42), "player101":("Tony Parker", 36);
nebula> LOOKUP ON player;
+-------------+
| _vid |
+-------------+
| "player100" |
+-------------+
| "player101" |
+-------------+
检索边类型为
like
的所有边的信息。nebula)> CREATE EDGE like(likeness int);
nebula)> CREATE EDGE INDEX like_index on like();
nebula> REBUILD EDGE INDEX like_index;
+------------+
| New Job Id |
+------------+
| 88 |
+------------+
nebula)> INSERT EDGE like(likeness) values "player100"->"player101":(95);
nebula)> LOOKUP ON like;
+-------------+----------+-------------+
| _src | _ranking | _dst |
+-------------+----------+-------------+
| "player100" | 0 | "player101" |
+-------------+----------+-------------+
计数点或边
计数标签为player
的点和边类型为like
的边。
nebula> LOOKUP ON player | YIELD COUNT(*) AS Player_Number;
+---------------+
| Player_Number |
+---------------+
| 2 |
+---------------+
nebula> LOOKUP ON like | YIELD COUNT(*) AS Like_Number;
+-------------+
| Like_Number |
+-------------+
| 1 |
+-------------+
FAQ
错误码411
[ERROR (-8)]: Unknown error(411):
错误码411
表示WHERE
过滤时没有有效的索引。Nebula Graph的索引使用的是最左匹配原则,即从最左边的为起点任何连续的索引都能匹配上。例如:
# 为标签t的前三个属性创建索引。
nebula> CREATE TAG INDEX example_index ON TAG t(p1, p2, p3);
# 无法匹配索引,因为不是从p1开始。
nebula> LOOKUP ON t WHERE p2 == 1 and p3 == 1;
# 可以匹配索引。
nebula> LOOKUP ON t WHERE p1 == 1;
# 可以匹配索引,因为p1和p2是连续的。
nebula> LOOKUP ON t WHERE p1 == 1 and p2 == 1;
# 可以匹配索引,因为p1、p2、p3是连续的。
nebula> LOOKUP ON t WHERE p1 == 1 and p2 == 1 and p3 == 1;
没有找到有效索引
No valid index found
如果您的查询过滤器包含字符串类型的字段,Nebula Graph会选择匹配所有字段的索引。例如:
nebula> CREATE TAG t1 (c1 string, c2 int);
nebula> CREATE TAG INDEX i1 ON t1 (c1, c2);
# 索引i1无效。
nebula> LOOKUP ON t1 WHERE t1.c1 == "a";
# 索引i1有效。
nebula> LOOKUP ON t1 WHERE t1.c1 == "a" and t1.c2 == 1;