之前一篇文章写了nebula图数据库的入门,今天具体讲一下nebula中的相关查询语法,nebula自己开发了一套ngql,同时也支持了部分cypher语句的查询,查询语法还是比较丰富的,对于初学者来说,具体场景应该使用哪种查询语句就会比较困惑。
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里面,也不可能全量扫描去反序列化属性值后再过滤,那样性能太差。
nebula里面创建索引的目的其实不是为了加快查询速度,创建索引其实是存储了一份以属性值为key的一份数据,这样才有可能根据属性是查找。
其实从各自的查询语法定义就可以看出一些不一样,GO、FETCH、GET SUBGRAPH、FIND PATH的语句都是开始需要指定VID,所以自然也就不需要依赖索引,而LOOKUP、MATCH没有要求必须指定VID,所以需要依赖索引才可以正常查询,没有索引的情况会直接返回错误。这样我们基本就可以区分了,如果你是需要基于属性值查询数据,你只能使用LOOKUP、MATCH,并且需要事先创建好索引。
我们再从业务场景来看,如果我们只是需要查看节点的属性,不关心节点的关系的化,我们可以使用GO、FETCH、LOOKUP、MATCH,具体我们再怎么选呢。
GO和MATCH是可以满足各种查询场景的,功能相对比较丰富一点,我们留到后面讨论。我们看一些FETCH和LOOKUP的区别。如果只是简单的根据VID查询,我建议使用FETCH查询,直接根据VID查询节点或边的属性值郑州治疗焦虑症哪个医院好https://jbk.39.net/yiyuanfengcai/hj_zzjsyy/
如果是需要根据一些条件查询的话,我们就可以使用LOOKUP,可以支持各种查询条件的组合
我们再看一些稍微复杂一点的场景,如上图用户-订单-商品的关系图,我们需要查询用户张三买了哪些产品,我们应该怎么查询呢?下面我们可以分别使用GO和MATCH查询
对于不熟悉GO和MATCH语法的,相信也能看懂大概的意思,稍微解释一下,GO语句中"Buy._dst"代表关系的终止节点,其中还用到了"|"管道符,用于把结果作为后面语句的入口,其中"-"代表前一条语句的结果,可以通过"?"代表前一条语句的结果,可以通过"-"获取相应的属性。MATCH语句就更好理解了,()代表一个节点,[]代表一个关系,通过-连接,其中箭头代表了方向,也可以不带箭头,就代表双向的关系。
现在如果我们需要查询出人到产品的完整路径,这时候我们怎么查呢?我们可以选择GET SUBGRAPH和MATCH,GET SUBGRAPH是专门用来查询子图的,涉及这种路径查询的,第一就想到用这个。MATCH语句只要把上面的查询稍微改一下就可以了。
下面是GET SUBGRAPH的定义,STEPS代表需要几跳的距离,然后是指定边的类型和方向,很好理解。
最后再介绍一下FIND PATH语句,主要是用来找出给定节点之间的路径,给定起始点和终止点,通过图算法帮你找出之间的所有路径,主要有三种路径类型,SHORTEST最短路径,ALL所有路径,NOLOOP非循环路径。
今天就把nebula中所有的查询语句都简单介绍了一下,不过要想熟练使用还是得多多练习,最后再给一个思考题,如果要查询买了可乐的用户还买了什么商品,这个应该怎么查询呢?