深入学习Gremlin(20):遍历栅栏barrier

第20期 Gremlin Steps:

barrier()

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

深入学习Gremlin(20):遍历栅栏barrier

上一期:深入学习Gremlin(19):结果存取口袋sack

遍历栅栏说明

Gremlin在路径遍历的时候,可以将栅栏barrier插入到懒加载的遍历流水线中,以使得barrier之前的步骤都执行完成之后再继续往下执行。barrier主要有2个好处:1、可以强制改变深度优先搜索为广度优先搜索,2、由于通过层的bulking模式可以优化大量重复的数据访问。

下面讲解实现上述功能的具体Step:

  • barrier(): 在某个位置插入一个栅栏,以强制该位置之前的步骤必须都执行完成才可以继续往后执行,比如g.V().both().barrier().both()只有在第一个both()全部完成之后才会执行第二个both()

实例讲解

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

  1. Step barrier(): 遍历时设置栅栏

    示例1:

    // 将所有顶点打印出来
    // 打印完一轮之后再打印一轮
    def list=[]
    g.V().sideEffect{list.add("first: "+it)}
         .barrier()
         .sideEffect{list.add("second: "+it)}
         .iterate()
    list
    

    深入学习Gremlin(20):遍历栅栏barrier

    对比无barrier时的效果:

    // 打印first后打印second,
    // 直到一轮所有的顶点都完成
    def list=[]
    g.V().sideEffect{list.add("first: "+it)}
         .sideEffect{list.add("second: "+it)}
         .iterate()
    list
    

    深入学习Gremlin(20):遍历栅栏barrier

    示例2:

    // 禁用自动barrier策略
    g = g.withoutStrategies(LazyBarrierStrategy)
    g.V()
     .both().barrier()
     .both().barrier()
     .both().barrier()
     .both().barrier()
     .both().barrier()
     .groupCount()
     .order(local).by(values, decr)
    

    深入学习Gremlin(20):遍历栅栏barrier

    对比无barrier时的效果(消耗时间更长):

    // 通过lambda函数来指定放入口袋的行为
    // 注意:提供的初始值为Map类型,而且
    // 当traverser分裂时会拷贝Map
    g = g.withoutStrategies(LazyBarrierStrategy)
    g.V()
     .both()
     .both()
     .both()
     .both()
     .both()
     .groupCount()
     .order(local).by(values, decr)
    

    深入学习Gremlin(20):遍历栅栏barrier

    注意:LazyBarrierStrategy是默认策略,该策略会在合适的地方插入barrier,因此这里先禁用了该策略。

  2. Step barrier()相关Step:

    事实上除了可显示的插入barrier栅栏外,还有不少Step会隐式插入barrier,包括 order(), sample(), dedup(), aggregate(), fold(), count(), sum(), max(), min(), group(), groupCount(), cap()等。

综合运用

  1. 计算特征向量中心性(Eigenvector Centrality)

    // 利用隐式barrier计算特征向量中心性
    // 包括groupCount、cap,按照降序排序
    g.V().repeat(both().groupCount('m'))
         .times(5).cap('m')
         .order(local).by(values, decr)
    

    深入学习Gremlin(20):遍历栅栏barrier

下一期:深入学习Gremlin(21):局部操作local