图查询语言 nGQL 简明教程 vol.01 快速入门

image

本文旨在让新手快速了解 nGQL,掌握方向,之后可以脚踩在地上借助文档写出任何心中的 NebulaGraph 图查询。

视频

本教程的视频版在B站这里

准备工作

在正式开始 nGQL 实操之前,记得先看过文档「快速入门流程」,部署、连接过 NebulaGraph,并且看过了「常用命令」。如果你还没看过这两个文档,为了跟上进度,记得先快速过一遍,上面两个文档链接可在文末「参考资料」中获取。

我们的目标是

本教程目的在于让大家大概知道了 NebulaGraph 的查询语句后,解决“不知道什么样的查询应该用什么语句”的问题。

nGQL 是什么

我们先强调一下概念:nGQL 是 NebulaGraph Query Language 的缩写,它表示 NebulaGraph 的查询语言,可以不严谨地分为这 5 部分:

  • NebulaGraph 独有 DQL(Data Query Language)查询语句
  • NebulaGraph openCypher DQL
  • NebulaGraph DML(Data Mutation Language)写语句
  • NebulaGraph DDL(Data Definition Language) Schema 语句
  • NebulaGraph Admin Queries 管理语句

这里,作为简明教程一把梭,我们只关注前两个部分,后边的内容会在 Part 2 中介绍。

nGQL 速查表 cheatsheet

大家可以保存下这份单页速查表,一次了解所有 nGQL 的用法。

image.png

NebulaGraph 独有 DQL

NebulaGraph 的独有读查询语句的设计非常简洁,对初学者非常友好。它结合了管道的概念,做到了只涉及了几个关键词就可以描述出大多数的图查询模式。由于篇幅的问题,所有 DQL 查询语句的更多用法记得查阅本文的「参考资料」

简单来说,nGQL 的独有 DQL 一共分成四类语句:

  • 图拓展 / 遍历:GO
  • 索引反查:LOOKUP
  • 取属性:FETCH
  • 路径与子图:FIND PATHGET SUBGRAPH

和两个特别的元素:

  • 管道:|
  • 引用属性: $ 开头的几个符号,用来描述一些特定的上下文

用 GO 来图拓展 / 遍历

GO 的语义非常直观:从给定的起点,向外拓展,按需返回终点、起点的信息。

# 图拓展
GO 3 STEPS FROM "player102" OVER follow YIELD dst(edge);
   ───┬───      ───┬───────      ─┬────       ──┬────── 
      │            │              │   ┌─────────┘       
      │            │              │   │                 
      │            │              │   └── 返回最后一跳边的终点
      │            │              │                     
      │            │              └────── 从 follow 这个边[出方向]探索
      │            │                                    
      │            └───────────────────── 起点是 "player102"
      │                                                 
      └────────────────────────────────── 探索 3 步

这里只是做了一个简单的 GO 语法示例,像 GO 实现的反向、双向拓展,指定可变跳数遍历等,更多 GO 语句用法可查阅参考资料。

LOOKUP 基于索引反查 ID

GO 的从已知的点出发相反,LOOKUP 是一个类似于 SQL 里 SELECT 语义的关键字,它实际的作用也类似与关系型数据库中的扫表

LOOKUP 需要手动创建相应 TAG、边类型上索引才能进行相关查询

为什么 LOOKUP 需要索引?

因为 NebulaGraph 中的数据默认是按照邻接表的形式存储,在分布式设计中,扫描一个类型的点、边是非常昂贵的,所以它被默认禁止了。NebulaGraph 索引的存在增加了类似于表结构数据库的排序数据,可以用来做像是 SELECT 的查询。

# 索引反查
LOOKUP ON player WHERE player.name == "Tony Parker" YIELD id(vertex);
          ──┬───  ──────┬──────────────────────────  ──┬──────       
            │           │          ┌───────────────────┘             
            │           │          │                                 
            │           │          └──────────── 返回查到点的 VID
            │           │                                            
            │           └─────────────────────── 过滤条件是属性 name 的值
            │                                                        
            └─────────────────────────────────── 根据点的类别/TAG player 查询

本文仅作 LOOKUP 语法的使用入门,关于索引原理和使用,比如:创建索引会有什么代价?索引会加速读么?记得查看文末的参考资料。

FETCH PROP 获取属性

如字面意思,如果我们知道一个点、边的 ID,想要获取它上边的属性,这时候我们要用 FETCH PROP 而非 LOOKUP

# 取属性
FETCH PROP ON player "player100" YIELD properties(vertex);
              ──┬───  ────┬─────       ─────────┬──────── 
                │         │         ┌───────────┘         
                │         │         │                     
                │         │         └─────── 返回点的 player TAG 下所有属性
                │         │                               
                │         └───────────────── 从 "player100" 这个点获取
                │                                         
                └─────────────────────────── 获取 player 这个 TAG 下的属性

路径查找 FIND PATH

如果我们要找到指定两点之间的所有路径,一定要用 FIND PATH

# 起点终点间路径
FIND SHORTEST PATH FROM "player102" TO "team204" OVER * \   
     ──┬─────            ───────────┬─────────── ───┬───    
  YIELD│path AS p; ┌────────────────┘               │       
       │────┬────  │     ┌──────────────────────────┘       
       │    │      │     │                                  
       │    │      │     └───────── 经由所有类型的边出向探索
       │    │      │                                        
       │    │      └─────────────── 从给定的起点、终点 VID
       │    │                                               
       │    └────────────────────── 返回路径为 p 列
       │                                                    
       └─────────────────────────── 查找最短路径

单点子图 GET SUBGRAPH

和路径查找类似,如果我们只给定一个起点和拓展步数,用 GET SUBGRAPH 可以帮我们获取同样的 BFS 出去的子图。

# 单点 BFS 子图

GET SUBGRAPH 5 STEPS FROM "player101" \           
             ───┬─── ─────┬──────────             
  YIELD VERTICES AS nodes, EDGES AS relationships;
        ────┬───┼─────────┼───────────────────────
   ┌────────┘   │         │                       
   │            │         └─────── 从 "player101" 开始触发
   │            │                                 
   │            └───────────────── 获取 5 步的探索
   │                                              
   └────────────────────────────── 返回所有的点、边

利用管道和属性引用符

NebulaGraph 的管道设计和 Unix-Shell 的设计很像,可以将简单的几种语句结合起来,有强大的表达力。

# 使用通道
GO FROM "player100" OVER follow YIELD dst(edge) AS did  | \  
    ─────┬──────────────────────────────────────────── ─┬─   
  GO FROM│$-.did OVER follow YIELD dst(edge);           │    
         │────┬──     ┌─────────────────────────────────┘    
         │    │       │                                      
         │    │       └──────── 管道将左边的 AS 输出作为右边语句输入
         │    │                                              
         │    └──────────────── 从管道左边的 did 属性开始探索
         │
         └───────────────────── 第一个查询语句

除了以上的集中表达之外,NebulaGraph 独有查询语句还有聚合的表达参考 GROUP-BY,另外在文档里还有一个 Cheatsheet供大家查询一些复杂的例子。

NebulaGraph openCypher DQL

从 NebulaGraph v2.0 起,openCypher 的 MATCH 语句也被 NebulaGraph 原生支持了。虽然 NebulaGraph 这里是一个“方言”,有一些使用细节差异。

MATCH <pattern> [<clause_1>] RETURN <output>  [<clause_2>];

MATCH 的基本表达是由 (v:tag_a) 包裹的点和 --> 或者 <-[:edge_type_1]- 表达的边组成的模式,再与 RETURN 结合表达输出。

如果你从 Cypher 的查询语言入门图数据库,可以从下边几个例子了解到若干 NebulaGraph 里的使用细节差异:

  • 增加了 WHERE id(v) == "foo" 的表达;
  • == 表达相等判断而不是 =
  • 点的属性表达需要填写 TAG,例如 v3.player.name 而不是 v3.name
MATCH (v:`player`{name:"Tim Duncan"})-->(v2)<--(v3) \
    RETURN v3.`player`.name AS Name;

MATCH (v:`player`) \
    WHERE NOT (v)--() \
    RETURN v;

MATCH (v:`player`)--(v2) \
    WHERE id(v2) IN ["player101", "player102"] \
    RETURN v;

MATCH (m)-[]->(n) WHERE id(m)=="player100" \
OPTIONAL MATCH (n)-[]->(l) WHERE id(n)=="player125" \
    RETURN id(m), id(n), id(l);

以上,为本次简明教程的第一集。

参考资料


谢谢你读完本文 (///▽///)

免部署省时省力,现在可以用用 NebulaGraph Cloud 来搭建自己的图数据系统哟~NebulaGraph 阿里云计算巢现 30 天免费使用中,点击链接来用用图数据库吧~

想看源码的小伙伴可以前往 GitHub 阅读、使用、(з)-☆ star 它 -> GitHub;和其他的 NebulaGraph 用户一起交流图数据库技术和应用技能,留下「你的名片」一起玩耍呢~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容