LOOKUP¶
LOOKUP
根据索引遍历数据。用户可以使用LOOKUP
实现如下功能:
- 根据
WHERE
子句搜索特定数据。
- 通过 Tag 列出点:检索指定 Tag 的所有点 ID。
- 通过 Edge type 列出边:检索指定 Edge type 的所有边的起始点、目的点和 rank。
- 统计包含指定 Tag 的点或属于指定 Edge type 的边的数量。
OpenCypher 兼容性¶
本文操作仅适用于原生 nGQL。
注意事项¶
- 索引会导致写性能大幅降低。请不要随意在生产环境中使用索引,除非很清楚使用索引对业务的影响。
-
通过
Explain
命令查看选择的索引。历史版本兼容性
在 2.5.0 版本之前,如果用
LOOKUP
语句基于指定属性查询时该属性没有索引,系统将报错,而不会使用其它索引。
前提条件¶
请确保LOOKUP
语句有至少一个索引可用。
如果已经存在相关的点、边或属性,必须在新创建索引后重建索引,才能使其生效。
语法¶
LOOKUP ON {<vertex_tag> | <edge_type>}
[WHERE <expression> [AND <expression> ...]]
YIELD [DISTINCT] <return_list> [AS <alias>]
[<clause>];
<return_list>
<prop_name> [AS <col_alias>] [, <prop_name> [AS <prop_alias>] ...];
WHERE <expression>
:指定遍历的过滤条件,还可以结合布尔运算符 AND 和 OR 一起使用。详情请参见 WHERE。
YIELD
:定义需要返回的输出。详情请参见YIELD
。
DISTINCT
:聚合输出结果,返回去重后的结果集。
AS
:设置别名。
clause
:支持ORDER BY
、LIMIT
子句。
WHERE 语句限制¶
在LOOKUP
语句中使用WHERE
子句,不支持如下操作:
$-
和$^
。- 在关系表达式中,不支持运算符两边都有字段名,例如
tagName.prop1 > tagName.prop2
。 - 不支持运算表达式和函数表达式中嵌套 AliasProp 表达式。
- 不支持 XOR 运算符。
- 不支持除
STARTS WITH
之外的字符串操作。 - 不支持过滤
rank()
。 - 不支持图模式.
检索点¶
返回 Tag 为player
且name
为Tony Parker
的点。
# 创建 Tag 为 player 的复合属性索引 index_player。
nebula> CREATE TAG INDEX IF NOT EXISTS index_player ON player(name(30), age);
# 重建复合属性索引 index_player,返回任务 id。
nebula> REBUILD TAG INDEX index_player;
+------------+
| New Job Id |
+------------+
| 15 |
+------------+
# 返回所有 name 等于 Tony Parker 的点数据的 ID。
nebula> LOOKUP ON player \
WHERE player.name == "Tony Parker" \
YIELD id(vertex);
+---------------+
| id(VERTEX) |
+---------------+
| "player101" |
+---------------+
# 查询所有 name 等于 Tony Parker 的点数据,返回 name 和 age 属性值。
nebula> LOOKUP ON player \
WHERE player.name == "Tony Parker" \
YIELD properties(vertex).name AS name, properties(vertex).age AS age;
+---------------+-----+
| name | age |
+---------------+-----+
| "Tony Parker" | 36 |
+---------------+-----+
# 查询所有 age 大于 45 的点数据,并返回点数据的 ID。
nebula> LOOKUP ON player \
WHERE player.age > 45 \
YIELD id(vertex);
+-------------+
| id(VERTEX) |
+-------------+
| "player144" |
| "player140" |
+-------------+
# 查询所有 name 以 B 开头,且 age 是 22 或 30 的点数据,并返回 name 和 age 属性值。
nebula> LOOKUP ON player \
WHERE player.name STARTS WITH "B" \
AND player.age IN [22,30] \
YIELD properties(vertex).name, properties(vertex).age;
+-------------------------+------------------------+
| properties(VERTEX).name | properties(VERTEX).age |
+-------------------------+------------------------+
| "Ben Simmons" | 22 |
| "Blake Griffin" | 30 |
+-------------------------+------------------------+
# 查询所有 name 等于 Kobe Bryant 的点数据,返回点的 ID 和 name 属性值,并以此为起始点进行遍历,返回遍历结果。
nebula> LOOKUP ON player \
WHERE player.name == "Kobe Bryant"\
YIELD id(vertex) AS VertexID, properties(vertex).name AS name |\
GO FROM $-.VertexID OVER serve \
YIELD $-.name, properties(edge).start_year, properties(edge).end_year, properties($$).name;
+---------------+-----------------------------+---------------------------+---------------------+
| $-.name | properties(EDGE).start_year | properties(EDGE).end_year | properties($$).name |
+---------------+-----------------------------+---------------------------+---------------------+
| "Kobe Bryant" | 1996 | 2016 | "Lakers" |
+---------------+-----------------------------+---------------------------+---------------------+
检索边¶
返回 Edge type 为follow
且degree
为90
的边。
# 创建 Edge type 为 follow,属性 degree 的索引 index_follow。
nebula> CREATE EDGE INDEX IF NOT EXISTS index_follow ON follow(degree);
# 重建属性索引 index_follow,返回任务 id。
nebula> REBUILD EDGE INDEX index_follow;
+------------+
| New Job Id |
+------------+
| 62 |
+------------+
# 查询并返回所有 degree 等于 90 的边。
nebula> LOOKUP ON follow \
WHERE follow.degree == 90 YIELD edge AS e;
+----------------------------------------------------+
| e |
+----------------------------------------------------+
| [:follow "player109"->"player125" @0 {degree: 90}] |
| [:follow "player118"->"player120" @0 {degree: 90}] |
| [:follow "player118"->"player131" @0 {degree: 90}] |
...
# 查询所有 degree 等于 90 的边,并返回 degree 属性值。
nebula> LOOKUP ON follow \
WHERE follow.degree == 90 \
YIELD properties(edge).degree;
+-------------------------+
| properties(EDGE).degree |
+-------------------------+
| 90 |
| 90 |
...
# 根据 degree 属性值升序排列,并返回前 10 条 degree 属性值。
nebula> LOOKUP ON follow \
YIELD properties(edge).degree as degree \
| ORDER BY $-.degree \
| LIMIT 10;
+--------+
| degree |
+--------+
| -1 |
| -1 |
| 9 |
| 10 |
| 13 |
| 50 |
| 55 |
| 60 |
| 70 |
| 70 |
+--------+
# 查询所有 degree 等于 60 的边,返回边的目的点 ID 和边的 degree 属性值,并为此起始点进行遍历,返回遍历结果。
nebula> LOOKUP ON follow \
WHERE follow.degree == 60 \
YIELD dst(edge) AS DstVID, properties(edge).degree AS Degree |\
GO FROM $-.DstVID OVER serve \
YIELD $-.DstVID, properties(edge).start_year, properties(edge).end_year, properties($$).name;
+-------------+-----------------------------+---------------------------+---------------------+
| $-.DstVID | properties(EDGE).start_year | properties(EDGE).end_year | properties($$).name |
+-------------+-----------------------------+---------------------------+---------------------+
| "player105" | 2010 | 2018 | "Spurs" |
| "player105" | 2009 | 2010 | "Cavaliers" |
| "player105" | 2018 | 2019 | "Raptors" |
+-------------+-----------------------------+---------------------------+---------------------+
通过 Tag 列出所有的对应的点/通过 Edge type 列出边¶
如果需要通过 Tag 列出所有的点,或通过 Edge type 列出边,则 Tag、Edge type 或属性上必须有至少一个索引。
例如一个 Tag player
有属性name
和age
,为了遍历所有包含 Tag player
的点 ID,Tag player
、属性name
或属性age
中必须有一个已经创建索引。
- 查找所有 Tag 为
player
的点 VID。# 创建名为 player 的 Tag。 nebula> CREATE TAG IF NOT EXISTS player(name string,age int); # 创建 Tag 为 player 的索引 player_index。 nebula> CREATE TAG INDEX IF NOT EXISTS player_index on player(); # 重建索引 player_index,返回任务 id。 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); # 列出所有的 player。类似于 MATCH (n:player) RETURN id(n) /*, n */。 nebula> LOOKUP ON player YIELD id(vertex); +-------------+ | id(VERTEX) | +-------------+ | "player100" | | "player101" | ... # 从结果中返回最前面的 4 行数据。 nebula> LOOKUP ON player YIELD id(vertex) | LIMIT 4; +-------------+ | id(VERTEX) | +-------------+ | "player105" | | "player109" | | "player111" | | "player118" | +-------------+
- 查找 Edge type 为
follow
的所有边的信息。# 创建名为 follow 的 Edge type。 nebula> CREATE EDGE IF NOT EXISTS follow(degree int); # 创建 Edge type 为 follow 的索引 follow_index。 nebula> CREATE EDGE INDEX IF NOT EXISTS follow_index on follow(); # 重建索引 follow_index。 nebula> REBUILD EDGE INDEX follow_index; +------------+ | New Job Id | +------------+ | 88 | +------------+ # 插入边数据。 nebula> INSERT EDGE follow(degree) \ VALUES "player100"->"player101":(95); # 列出所有的 follow 边。类似于 MATCH (s)-[e:follow]->(d) RETURN id(s), rank(e), id(d) /*, type(e) */。 nebula)> LOOKUP ON follow YIELD edge AS e; +-----------------------------------------------------+ | e | +-----------------------------------------------------+ | [:follow "player105"->"player100" @0 {degree: 70}] | | [:follow "player105"->"player116" @0 {degree: 80}] | | [:follow "player109"->"player100" @0 {degree: 80}] | ...
统计点或边¶
统计 Tag 为player
的点和 Edge type 为follow
的边。
# 统计 Tag 为 player 的点总数。
nebula> LOOKUP ON player YIELD id(vertex)|\
YIELD COUNT(*) AS Player_Number;
+---------------+
| Player_Number |
+---------------+
| 51 |
+---------------+
# 统计 Edge type 为 follow 的边总数。
nebula> LOOKUP ON follow YIELD edge AS e| \
YIELD COUNT(*) AS Follow_Number;
+---------------+
| Follow_Number |
+---------------+
| 81 |
+---------------+
Note
使用 SHOW STATS
命令也可以统计点和边。
最后更新:
September 6, 2024