循环操作

循环操作是指多次执行某一部分语句,用于语句需要重复运行的场景,比如“查找朋友的朋友的朋友”,可以直接使用循环操作来完成。

  • 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():按照指定的次数重复执行语句

示例:

  1. // 访问顶点"2:HugeGraph"的out邻接点(1次)
  2. g.V('2:HugeGraph').both().both().cyclicPath().path()
  3. // 访问顶点"2:HugeGraph"的双向邻接点(2层)
  4. // 即:访问顶点"2:HugeGraph"的双向邻接点,然后再继续访问第一层结果顶点的邻接点
  5. // 等价于 g.V('s:HugeGraph').both().both()
  6. g.V('2:HugeGraph').repeat(both()).times(2)

repeat() + until()

Step repeat() + until():根据条件来重复执行语句

示例:

  1. // 获取顶点"3:Gremlin"的双向邻接点,向下循环双向邻接点
  2. // 循环的终止条件是遇到 name="Jermy Li"的顶点
  3. g.V('3:Gremlin').repeat(both()).until(has('name', 'Jermy Li')).path()

until()times()是互斥的,两个语句无法同时存在于同一个循环中。

until()放在repeat()之前或者之后的顺序是会影响逻辑的。until()放在前面表示先判断后执行,放到后面表示先执行后判断。

repeat() + emit()

Step repeat() + emit():收集执行过程中的数据

示例:

  1. // 查询顶点"2:HugeGraph"的所有OUT可达点的路径
  2. g.V('2:HugeGraph').repeat(out()).emit().path()
  3. // 查询顶点"2:HugeGraph"的所有OUT可达点的路径,且 lang=java
  4. g.V('2:HugeGraph').repeat(out()).emit(has('lang','java')).path()

emit()放在repeat()之前或者之后的顺序是会影响结果的,放前面表示先收集再执行,放后面表示先执行后收集。

repeat() + until() + emit()

emit()until() 搭配使用时,是的关系,满足两者间任意一个即可。

示例:

  1. // 访问顶点"okram"的2度OUT可达点的路径
  2. // 此外还收集 label='person'的顶点
  3. // 顶点"spmallette"是顶点"okram"的第1层OUT可达点,不满足2度OUT可达点,但是因为顶点"spmallette"的label='person',所以会被emit收集到
  4. g.V('okram')
  5. .repeat(out())
  6. .times(2)
  7. .emit(hasLabel('person'))
  8. .path()

repeat() + loops()

Step repeat() + loops():根据最大次数限制来重复执行语句

示例:

  1. // 查询顶点"okram"的3度OUT可达点路径
  2. g.V('okram').repeat(out()).until(loops().is(3)).path()

until()使用组合条件

until()中可以使用and()将两个条件组合。

示例:

  1. // 查询顶点"okram"的2度可达点,且可达点属性lang='java'
  2. g.V('okram')
  3. .repeat(out())
  4. .until(has('lang','java').and().loops().is(2))
  5. // 查询顶点'okram'到顶点'Gremlin'之间的路径
  6. // 且之间只相差2跳的距离
  7. g.V('okram')
  8. .repeat(out())
  9. .until(has('name', 'Gremlin')
  10. .and().loops().is(2))
  11. .path()

综合使用

查找子树:

  1. // 查找"okram"顶点出发,到叶子节点结束的所有路径
  2. g.V('okram').repeat(out())
  3. .until(outE().count().is(0)) // 叶子节点没有向外的边,outE()的数量为0
  4. .path()