深入学习Gremlin(20):遍历栅栏barrier
第20期 Gremlin Steps:
barrier()
本系列文章的Gremlin示例均在HugeGraph图数据库上执行,环境搭建可参考准备Gremlin执行环境,本文示例均以其中的“TinkerPop关系图”为初始数据,如下图所示:
上一期:深入学习Gremlin(19):结果存取口袋sack
遍历栅栏说明
Gremlin在路径遍历的时候,可以将栅栏barrier插入到懒加载的遍历流水线中,以使得barrier之前的步骤都执行完成之后再继续往下执行。barrier主要有2个好处:1、可以强制改变深度优先搜索为广度优先搜索,2、由于通过层的bulking模式可以优化大量重复的数据访问。
下面讲解实现上述功能的具体Step:
-
barrier()
: 在某个位置插入一个栅栏,以强制该位置之前的步骤必须都执行完成才可以继续往后执行,比如g.V().both().barrier().both()
只有在第一个both()
全部完成之后才会执行第二个both()
。
实例讲解
下面通过实例来深入理解每一个操作。
-
Step
barrier()
: 遍历时设置栅栏示例1:
// 将所有顶点打印出来 // 打印完一轮之后再打印一轮 def list=[] g.V().sideEffect{list.add("first: "+it)} .barrier() .sideEffect{list.add("second: "+it)} .iterate() list
对比无barrier时的效果:
// 打印first后打印second, // 直到一轮所有的顶点都完成 def list=[] g.V().sideEffect{list.add("first: "+it)} .sideEffect{list.add("second: "+it)} .iterate() list
示例2:
// 禁用自动barrier策略 g = g.withoutStrategies(LazyBarrierStrategy) g.V() .both().barrier() .both().barrier() .both().barrier() .both().barrier() .both().barrier() .groupCount() .order(local).by(values, decr)
对比无barrier时的效果(消耗时间更长):
// 通过lambda函数来指定放入口袋的行为 // 注意:提供的初始值为Map类型,而且 // 当traverser分裂时会拷贝Map g = g.withoutStrategies(LazyBarrierStrategy) g.V() .both() .both() .both() .both() .both() .groupCount() .order(local).by(values, decr)
注意:LazyBarrierStrategy是默认策略,该策略会在合适的地方插入barrier,因此这里先禁用了该策略。
-
Step
barrier()
相关Step:事实上除了可显示的插入barrier栅栏外,还有不少Step会隐式插入barrier,包括 order(), sample(), dedup(), aggregate(), fold(), count(), sum(), max(), min(), group(), groupCount(), cap()等。
综合运用
-
计算特征向量中心性(Eigenvector Centrality)
// 利用隐式barrier计算特征向量中心性 // 包括groupCount、cap,按照降序排序 g.V().repeat(both().groupCount('m')) .times(5).cap('m') .order(local).by(values, decr)