Chapter 6. Gremlin Query Language

Gremlin

Gremlin是janusgraph的查询语言,用来获取/变更图数据。Gremlin是一个面向path的语言,能够简单快速的完成图遍历和变化操作。Gremlin是一个功能性语言,因此遍历操作被声明到类path的表达式表单。例如,from Hercules, traverse to his father and then his father’s father and return the grandfather’s name

Gremlin是Apache TinkerPop的组件。它独立于janusgraph发展,并且被支持于大多数图数据库。建在janusgraph上的应用程序通过Gremlin查询语言,用户避免被发行商锁在一个图数据库上。

这章是Gremlin查询语言的简要概述。更多信息可以参考以下资源:

6.1 图遍历的介绍

一次Gremlin查询是一串从左到右的操作/函数链。下面是一个上帝图里举过的祖父查询例子:

gremlin> g.V().has('name', 'hercules').out('father').out('father').values('name')
==>saturn

上面的查询可以分成以下步骤:

  1. g: 当前graph。
  2. V: graph中所有顶点。
  3. has('name', 'hercules'): 过滤出顶点有属性name = "hercules" (这里只有一个)。
  4. out('father'): 从Hercules遍历出边(outgoing edge)为father的顶点。
  5. out('father'): 从Hercules的father (Jupiter)遍历出边为father的顶点。
  6. name: 拿出顶点的name属性的value。

放到一起,这些步骤构成了类似遍历查询的路径。每一步都能分解且得到结果。当构造大型、复杂的查询链,这种图遍历/查询的风格是很有用的。

gremlin> g
==>graphtraversalsource[janusgraph[cql:127.0.0.1], standard]
gremlin> g.V().has('name', 'hercules')
==>v[24]
gremlin> g.V().has('name', 'hercules').out('father')
==>v[16]
gremlin> g.V().has('name', 'hercules').out('father').out('father')
==>v[20]
gremlin> g.V().has('name', 'hercules').out('father').out('father').values('name')
==>saturn

正常情况,通常看到返回的属性更好,而不是分配的id。

gremlin> g.V().has('name', 'hercules').values('name')
==>hercules
gremlin> g.V().has('name', 'hercules').out('father').values('name')
==>jupiter
gremlin> g.V().has('name', 'hercules').out('father').out('father').values('name')
==>saturn

下面例子显示了完整的father家族树。这个复杂些的例子说明了这个语言的灵活性和便利性。熟练掌握Gremlin使得用户使用junasgraph图结构如鱼得水。

gremlin> g.V().has('name', 'hercules').repeat(out('father')).emit().values('name')
==>jupiter
==>saturn

下面是更多图遍历例子:

gremlin> hercules = g.V().has('name', 'hercules').next()
==>v[1536]
gremlin> g.V(hercules).out('father', 'mother').label()
==>god
==>human
gremlin> g.V(hercules).out('battled').label()
==>monster
==>monster
==>monster
gremlin> g.V(hercules).out('battled').valueMap()
==>{name=nemean}
==>{name=hydra}
==>{name=cerberus}

每一步(.分开)是一个函数,操作前一步结果的对象,Gremlin有很多步骤Gremlin steps。简单的改变一个步骤或步骤的顺序,会执行不同的遍历语义,下面的例子是和Hercules打过同样的怪兽,但不是Hercules的所有人的name。(类似战友、盟友)
给定的上帝图只有一个和怪兽战斗的,所以这里增加一个战士到图里。

gremlin> theseus = graph.addVertex('human')
==>v[3328]
gremlin> theseus.property('name', 'theseus')
==>null
gremlin> cerberus = g.V().has('name', 'cerberus').next()
==>v[2816]
gremlin> battle = theseus.addEdge('battled', cerberus, 'time', 22)
==>e[7eo-2kg-iz9-268][3328-battled->2816]
gremlin> battle.values('time')
==>22

当增加顶点时,顶点的label是选填。增加边时label必须提供。顶点或边都可以设置kv对的属性。当一个属性key的种类设置为SET或LIST,这个key的属性每一个必须用addProperty增加到顶点。

gremlin> g.V(hercules).as('h').out('battled').in('battled').where(neq('h')).values('name')
==>theseus

这个例子有4个链的函数,out, in, except, 和values,每个函数的输入输出类型如下表,V是顶点,U是Object,V是U的子集。

  1. out: V -> V
  2. in: V -> V
  3. except: U -> U
  4. values: V -> U

当把函数连起来,输入类型必须等于输出类型,U匹配所有。

注意

这样的Gremlin说的是在Gremlin
Console用的Gremlin-Groovy。Gremlin也有其他的语言支持drivers,variants

6.2 执行遍历

Gremlin Console的一个方便的特性是它自动生成所有结果,从终端执行查询。它在REPL环境工作很好,返回String类型的结果。当你过渡到Gremlin应用程序,理解如何明确的执行遍历很重要,因为不会自动的执行。下面是常用的方法来执行遍历:

  • iterate() - 不期待结果或可以被忽略。
  • next() - 拿到一个结果,确保用hasNext()检查。
  • next(int n) - 拿到n个结果,确保用hasNext()检查。
  • toList() - 获得所有结果作为list,如果没有则返回空的list。

下面是一端java代码说明这个概念:

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

推荐阅读更多精彩内容

  • 简介 JanusGraph的优势 JanusGraph在设计上针对图操作进行了优化,以便进行大规模的图运算,它的计...
    凌冰_lonny阅读 1,771评论 0 1
  • Gremlin是JanusGraph的查询语言,用于从图中检索数据和修改图中的数据。 Gremlin是一种面向路径...
    凌冰_lonny阅读 3,885评论 0 0
  • 这章节的这个例子扩了一个玩具图的扩展使用,是建在janusgraph叫 The Graph of the Gods...
    水他阅读 816评论 0 49
  • 甲图是一个构成的结构的顶点和边缘。顶点和边都可以有任意数量的键/值对称为属性。顶点表示离散对象,例如人,地点或事件...
    达微阅读 3,111评论 0 8
  • 昨夜和东风,细雨烟成守。 自是春风早早到,遍地樱花厚。 灯火映黄昏,独自相思候! 最怕残花凋落时,泪沾别离受!
    无痕_58d0阅读 251评论 0 1