目录
1、查询方式
按需不需要基于索引查询,可以分为两类:
为什么有的需要索引?
go(依据路径查询属性)
fetch (获取指定边、点的属性值)
lookup
match
1、查询方式
nebula可以用来查询的语句关键字主要有:GO、FETCH、LOOKUP、MATCH、GET SUBGRAPH、FIND PATH。
按需不需要基于索引查询,可以分为两类:
- 需要索引:LOOKUP、MATCH
- 不需要索引:GO、FETCH、GET SUBGRAPH、FIND PATH。
为什么有的需要索引?
- 因为nebula底层数据存储是基于RocksDB,是一种K-V的存储结构,nebula存储数据的时候,key是基于VID生成的,也就是点的唯一标识ID,而属性则经过序列化后存储到value里面了,所以正常情况下,是没有办法根据属性值过滤数据,因为属性根本不在key里面,也不可能全量扫描去反序列化属性值后再过滤,那样性能太差。
- 创建索引的目的其实不是为了加快查询速度,创建索引其实是存储了一份以属性值为key的一份数据,这样才有可能根据属性是查找。
其实从各自的查询语法定义就可以看出一些不一样:
-
GO、FETCH、GET SUBGRAPH、FIND PATH的语句都是开始需要指定VID,所以自然也就不需要依赖索引,
- LOOKUP、MATCH没有要求必须指定VID,所以需要依赖索引才可以正常查询,没有索引的情况会直接返回错误。
这样我们基本就可以区分了,如果你是需要基于属性值查询数据,你只能使用LOOKUP、MATCH,并且需要事先创建好索引。
从业务场景来看,如果我们只是需要查看节点的属性,不关心节点的关系的化,我们可以使用GO、FETCH、LOOKUP、MATCH。
FETCH和LOOKUP的区别:
- 如果只是简单的根据VID查询,我建议使用FETCH查询,直接根据VID查询节点或边的属性值
- 如果是需要根据一些条件查询的话,我们就可以使用LOOKUP,可以支持各种查询条件的组合
go(依据路径查询属性)
# 从 vid 为 player102 的点出发,并且通过边 server 相连的顶点,并依次输出边的属性,起点 vid,终点 vid,起点属性,终点属性
GO FROM "player102" OVER serve
yield
properties(edge) as edge_prop ,
src(edge) as start_vertex_id ,
dst(edge) as end_vertex_id,
properties($^) as start_vertex_prop,
properties($$) as end_vertex_prop;
# 以 player101 为出发点,经过任意类型的边,且经过 1 - 2 跳,并输出所有边的标签,起点 vid,终点vid
go 1 to 2 steps from "player101" over *
yield
type(edge)as edge_type,
src(edge) as start_vertex_id ,
dst(edge) as end_vertex_id;
# 由 player100 顶点出发,经过标签为 follow 的边,共两步,并输出边的起点和边的终点,以及终点边的 age 属性。然后将结果按照边的目的顶点进行分组。最后输出边的终点,起点和 age.
GO 2 STEPS FROM "player100" OVER follow
YIELD
src(edge) AS src,
dst(edge) AS dst,
properties($$).age AS age
| GROUP BY $-.dst
YIELD
$-.dst AS dst,
collect_set($-.src) AS src,
collect($-.age) AS age;
fetch (获取指定边、点的属性值)
# 获取点 player100 的所有属性
FETCH PROP ON player "player100";
# 获取 player100 的 name 属性
FETCH PROP ON player "player100"
YIELD
properties(vertex).name AS name;
# 获取顶点标签不同,但是顶点 id 相同的两个顶点的属性,并且将结果合并输出
FETCH PROP ON player, t1 "player100";
# 获取任意标签下,id 为 player100, player106, team200 的属性。
FETCH PROP ON * "player100", "player106", "team200";
# 获取连接 player100 和 team204 的边 serve 的所有属性值。
FETCH PROP ON serve "player100" -> "team204";
# 获取多条边的属性值
FETCH PROP ON serve "player100" -> "team204", "player133" -> "team202";
# 使用 rank 查询(默认会返回 rank 为 0 的边)
FETCH PROP ON serve "player100" -> "team204" @1;
lookup
# 查询所有带标签为 tag_name 的顶点的 vid 和属性
lookup on tag_name
yield
id(vertex) as vertex_id,
properties(vertex);
# 按照属性查询顶点
lookup on tag_name
where tag_name.name=="vertex_src_name"
yield
properties(vertex);
# 依据属性查询边
lookup on edge_name
where edge_name.name=="edge_name_1"
yield
properties(edge).key as key;
# 查询属性为某几个值
lookup on player
where player.age in [45,40,35]
yield
properties(vertex).name as name,
properties(vertex).age as age;
# 设置输出的个数(从第一位开始输出,输出两条记录)
lookup on player
where player.age in [45,40,35]
yield
properties(vertex).name as name,
properties(vertex).age as age |
limit 0,2;
# 查询并按属性排序
lookup on player
where player.age >= 30
yield properties(vertex).name as name,
properties(vertex).age as age
| order by $-.age desc;
# 使用 group 语句对结果进行分组
lookup on player
yield
properties(vertex).name as name,
properties(vertex).age as age
| group by
$-.age yield $-.age,
count($-.age) as res_num
| order by $-.res_num desc
| limit 3,7
match
# 查询所有标签为 tag_name 的顶点
match (m:tag_name)
return m;
# 查询 vid 为 "vertex_id" 的顶点
match (m:tag_name)
where id(m) == "vertex_id"
return m;
# 依据属性查询顶点
match (m:tag_name{name:"vertex_src_name"})
return m;
# 匹配查询路径(双向 "--";单向 "-->" 或 "<--")
match p=(m:tag_name)--(n:tag_name)
return p
# 也可写作(与 cypher 语法类似)
match (m:tag_name)-[p]->(n:tag_name)
return p
2、概念理解
实体和表分为两类:
- vertex(顶点、实体):tag_name(表)
- edge(边,关系):edge_type(表)