循环操作
循环操作是指多次执行某一部分语句,用于语句需要重复运行的场景,比如“查找朋友的朋友的朋友”,可以直接使用循环操作来完成。
repeat()
:指定要重复的语句,如repeat(out('friend'))
times()
:指定要重复执行的次数,如执行3次repeat(out('friend')).times(3)
unitl()
:指定循环终止的条件,如一只找到某个名字的朋友为止repeat(out('friend')).until(has('name', 'xiaofang'))
emit()
:指定循环语句的执行过程中收集数据的条件,每一步的结果只要符合条件则被收集,不指定条件时收集所有结果loops()
:当前循环的次数,可用于控制最大循环次数,如最多执行3次repeat(out('friend')).unitl(loops().is(3))
repeat() + times()
Step repeat()
+ times()
:按照指定的次数重复执行语句
示例:
// 访问顶点"2:HugeGraph"的out邻接点(1次)
g.V('2:HugeGraph').both().both().cyclicPath().path()
// 访问顶点"2:HugeGraph"的双向邻接点(2层)
// 即:访问顶点"2:HugeGraph"的双向邻接点,然后再继续访问第一层结果顶点的邻接点
// 等价于 g.V('s:HugeGraph').both().both()
g.V('2:HugeGraph').repeat(both()).times(2)
repeat() + until()
Step repeat()
+ until()
:根据条件来重复执行语句
示例:
// 获取顶点"3:Gremlin"的双向邻接点,向下循环双向邻接点
// 循环的终止条件是遇到 name="Jermy Li"的顶点
g.V('3:Gremlin').repeat(both()).until(has('name', 'Jermy Li')).path()
until()
和times()
是互斥的,两个语句无法同时存在于同一个循环中。
until()
放在repeat()
之前或者之后的顺序是会影响逻辑的。until()
放在前面表示先判断后执行,放到后面表示先执行后判断。
repeat() + emit()
Step repeat()
+ emit()
:收集执行过程中的数据
示例:
// 查询顶点"2:HugeGraph"的所有OUT可达点的路径
g.V('2:HugeGraph').repeat(out()).emit().path()
// 查询顶点"2:HugeGraph"的所有OUT可达点的路径,且 lang=java
g.V('2:HugeGraph').repeat(out()).emit(has('lang','java')).path()
emit()
放在repeat()
之前或者之后的顺序是会影响结果的,放前面表示先收集再执行,放后面表示先执行后收集。
repeat() + until() + emit()
emit()
与 until()
搭配使用时,是或
的关系,满足两者间任意一个即可。
示例:
// 访问顶点"okram"的2度OUT可达点的路径
// 此外还收集 label='person'的顶点
// 顶点"spmallette"是顶点"okram"的第1层OUT可达点,不满足2度OUT可达点,但是因为顶点"spmallette"的label='person',所以会被emit收集到
g.V('okram')
.repeat(out())
.times(2)
.emit(hasLabel('person'))
.path()
repeat() + loops()
Step repeat()
+ loops()
:根据最大次数限制来重复执行语句
示例:
// 查询顶点"okram"的3度OUT可达点路径
g.V('okram').repeat(out()).until(loops().is(3)).path()
until()使用组合条件
until()
中可以使用and()
将两个条件组合。
示例:
// 查询顶点"okram"的2度可达点,且可达点属性lang='java'
g.V('okram')
.repeat(out())
.until(has('lang','java').and().loops().is(2))
// 查询顶点'okram'到顶点'Gremlin'之间的路径
// 且之间只相差2跳的距离
g.V('okram')
.repeat(out())
.until(has('name', 'Gremlin')
.and().loops().is(2))
.path()
综合使用
查找子树:
// 查找"okram"顶点出发,到叶子节点结束的所有路径
g.V('okram').repeat(out())
.until(outE().count().is(0)) // 叶子节点没有向外的边,outE()的数量为0
.path()