深入学习Gremlin(22):遍历终止操作

第22期 Gremlin Steps:

hasNext()next()tryNext()toList()toSet()toBulkSet()fill()iterate()

本系列文章的Gremlin示例均在HugeGraph图数据库上执行,环境搭建可参考准备Gremlin执行环境,本文示例均以其中的“TinkerPop关系图”为初始数据。

tinkerpop关系图

上一期:深入学习Gremlin(21):待添加

说明

Gremlin 中有一类特殊的操作,它能够终止遍历器的“遍历”行为,使其执行并返回结果。在这里要强调的一点:原生的 Gremlin 语句通常都是用遍历器连接起来的,但其实这些连接的过程并不会执行 Gremlin 语句,只有走到了terminalStep 时才会执行。这个模式类似于 Spark 中对RDDmapaction操作。

  • hasNext: 判断遍历器是否含有元素(结果),返回布尔值;
  • next: 不传参数时获取遍历器的下一个元素,也可以传入一个整数 n,则获取后面 n 个元素;
  • tryNext: hasNextnext的结合版,返回一个Optional对象,如果有结果还需要调用get()方法才能拿到;
  • toList: 将所有的元素放到一个List中返回;
  • toSet: 将所有的元素放到一个Set中返回,会去除重复元素;
  • toBulkSet: 将所有的元素放到一个能排序的List中返回,重复元素也会保留;
  • fill: 传入一个集合对象,将所有的元素放入该集合并返回,其实toListtoSettoBulkSet就是通过fillStep实现的;
  • iterate: 这个 Step 在终止操作里面有点特殊,它并不完全符合终止操作的定义。它会在内部迭代完整个遍历器但是不返回结果。

那肯定有细心的同学要问了,前面我们介绍了那么多的 Step 很多都没有加terminalStep 啊,为什么也能返回结果呢?其实这是 Tinkerpop 的 Gremlin 解析引擎对遍历器对象调用了一个IteratorUtils.asList()方法,又调用了它内部的fill()方法(注意:不是上面讲到的fill()Step)。

实例讲解

下面通过实例来深入理解每一个操作。

  1. Step hasNext()

    示例1:

    // 判断顶点“linary”是否包含“created”出顶点
    g.V('linary').out('created').hasNext()
    

    示例2:

    // 判断顶点“linary”是否包含“knows”出顶点
    g.V('linary').out('knows').hasNext()
    
  2. Step next()

    示例1:

    // 获取顶点“javeme”的“knows”出顶点集合的下一个(第1个)
    g.V('javeme').out('knows').next()
    

    g.V('javeme').out('knows')返回的是一个遍历器(迭代器),每次执行这句话实际上都是获取的迭代器的第一个元素,那如果想获取第二个元素该怎么写呢?很简单,执行两次next()即可,但是这里的前提条件是遍历器中确实存在多个元素。

    示例2:

    // 获取顶点“javeme”的“knows”出顶点集合的下一个(第2个)
    it = g.V('javeme').out('knows')
    it.next()
    it.next()
    

    示例3:

    // 获取顶点“javeme”的“knows”出顶点集合的前两个
    g.V('javeme').out('knows').next(2)
    

    next()next(n)使用中有一点小小的区别,就是当没有元素或者没有足够多的元素时,执行next()会报错,但是执行next(n)则是返回一个空集合(List)。

  3. Step tryNext()

    示例1:

    // 试图获取顶点“javeme”的“created”出顶点集合中的下一个
    g.V('javeme').out('created').tryNext()
    

    这里细心的读者会发现结果与前面概述中说的有些不同。概述中说的是返回一个Optional对象,要获取Optional对象里的值是需要调用它的get()方法的,怎么这里直接就把值给返回了呢?大家先别着急,我们再看一个例子。

    示例2:

    // 试图获取顶点“javeme”的“created”入顶点集合中的下一个
    g.V('javeme').in('created').tryNext()
    

    这里更加令人费解,没有“created”入顶点时竟然直接报错了,其实这是HugeGraph的实现中关于Optional的序列化所致。HugeGraph序列化Optional对象时会判断该对象内的值是否存在,如果存在则取出来序列化该值,否则填入一个null。详细代码见HugeGraphSONModule.java中关于OptionalSerializer的实现。

    本文的重点在于学习Gremlin语法本身,下面给出上述两个示例的预期结果:

    Optional[v[3:HugeGraph]]
    Optional.empty
    
  4. Step toList()

    示例1:

    // 获取所有“person”顶点的“created”出顶点集合,放入List中,允许包含重复结果
    g.V().hasLabel('person').out('created').toList()
    

    示例2:

    // 获取所有“person”顶点的“created”入顶点集合,放入List中,允许包含重复结果
    g.V().hasLabel('person').in('created').toList()
    

    结果与next(n)有些类似。

  5. Step toSet()

    示例1:

    // 获取所有“person”顶点的“created”出顶点集合,放入Set中,不允许包含重复结果
    g.V().hasLabel('person').out('created').toSet()
    

    相比于toListtoSet去除了重复元素。

    示例2:

    // 获取所有“person”顶点的“created”入顶点集合,放入Set中,不允许包含重复结果
    g.V().hasLabel('person').in('created').toSet()
    
  6. Step toBulkSet()

    示例1:

    // 获取所有“person”顶点的“created”出顶点集合,放入BulkSet中,允许包含重复结果,排序
    g.V().hasLabel('person').out('created').toBulkSet()
    

    所谓的BulkSet虽然名字上带有"Set",但还是更像一个List,对比toList的结果,它实际上是把所有元素排了个序。

  7. Step fill()

    示例1:

    // 创建一个List,获取所有“person”顶点的“created”出顶点,并放入该List中
    results = []
    g.V().hasLabel('person').out('created').fill(results)
    results
    
  8. Step iterate()

    示例1:

    // 迭代所有“person”顶点
    it = g.V().hasLabel('person').iterate()
    it.hasNext()
    

    调用了iterate()后遍历器内部的元素就已经全部迭代过了,所以再调用hasNext()返回false。

下一期:深入学习Gremlin(23):待添加

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

推荐阅读更多精彩内容