学习Gremlin - 7.循环操作

7.循环操作

7.1、说明

循环操作是指多次执行某一部分语句,用于语句需要重复运行的场景,比如“查找朋友的朋友的朋友”,可以直接使用循环操作来完成即“查找3层朋友”,下面对具体的循环相关的Step进行说明:

  • repeat(): 指定要重复执行的语句,如repeat(out(‘friend’))
  • times(): 指定要重复执行的次数,如执行3次repeat(out(‘friend’)).times(3)
  • until(): 指定循环终止的条件,如一直找到某个名字的朋友为止
  • repeat(out(‘friend’)).until(has(‘name’,‘xiaofang’))
  • emit(): 指定循环语句的执行过程中收集数据的条件,每一步的结果只要符合条件则被收集,不指定条件时收集所有结果
  • loops(): 当前循环的次数,可用于控制最大循环次数等,如最多执行3次
  • repeat(out(‘friend’)).until(loops().is(3))

7.2、实例讲解

7.2.1、 repeat() + times():按照指定的次数重复执行语句
// 访问某个顶点的OUT邻接点(1次)
// 注意'okram'是顶点的id
g.V('okram').repeat(out()).times(1)
// 访问某个顶点的2度双向邻接点
// 访问第1个顶点的所有邻接点(第1层)
// 再访问第1层结果顶点的邻接点(第2层)
g.V('okram').repeat(both()).times(2)
// 访问某个顶点的3度OUT邻接点
// 访问第1个顶点的所有邻接点(第1层)
// 再访问第1层结果顶点的邻接点(第2层)
// 再访问第2层结果顶点的邻接点(第3层)
g.V('okram').repeat(out()).times(3)
7.2.2、 repeat() + until():根据条件来重复执行语句
// 查询顶点'okram'到顶点'Gremlin'之间的路径
// 循环的终止条件是遇到名称是'Gremlin'的顶点
g.V('okram')
    .repeat(out())
    .until(has('name', 'Gremlin'))
    .path()

注意1:这里用到了path()来获取经过的路径,path的讲解请参考上一期。

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

注意3:until()放在repeat()之前或之后的顺序是会影响逻辑的,放前面表示先判断再执行,放后面表示先执行后判断。请对比如下两个语句的执行结果:
g.V(‘okram’).repeat(out()).until(hasLabel(‘person’)).path()
g.V(‘okram’).until(hasLabel(‘person’)).repeat(out()).path()

7.2.3、 repeat() + emit():收集执行过程中的数据
// 查询顶点'okram'的所有OUT可达点的路径
g.V('okram')
	.repeat(out())
    .emit()
    .path()
// 查询顶点'okram'的所有OUT可达点的路径
// 且必须满足是'person'类型的点
g.V('okram')
    .repeat(out())
    .emit(hasLabel('person'))
    .path()

注意:emit()放在repeat()之前或之后的顺序是会影响结果的,放前面表示先收集再执行,放后面表示先执行后收集。请对比如下两个语句的执行结果:
g.V(‘okram’).repeat(out()).emit(hasLabel(‘person’)).path()
g.V(‘okram’).emit(hasLabel(‘person’)).repeat(out()).path()

// 查询顶点'okram'到顶点'Gremlin'之间的路径
// 此外还收集过程中的'person'类型的顶点
g.V('okram')
    .repeat(out())
    .until(has('name', 'Gremlin'))
    .emit(hasLabel('person'))
    .path()

注意:emit()until()搭配使用时,是“或”的关系而不是“与”的关系,满足两者间任意一个即可。

// 查询顶点'okram'的2度OUT可达点的路径
// 此外还收集'person'类型的顶点
g.V('okram')
    .repeat(out()).times(2)
    .emit(hasLabel('person'))
    .path()

注意:emit()times()搭配使用时,是“或”的关系而不是“与”的关系,满足两者间任意一个即可。

7.2.4、 repeat() + loops():根据最大次数限制来重复执行语句
// 查询顶点'okram'的3度OUT可达点路径
g.V('okram')
    .repeat(out())
    .until(loops().is(3))
    .path()
// 查询顶点'okram'到顶点'Gremlin'之间的路径
// 且之间只相差2跳的距离
// 其中的and()是指两个条件都满足
g.V('okram')
    .repeat(out())
    .until(has('name', 'Gremlin')
    	.and().loops().is(2))
    .path()

7.3、综合运用

7.3.1、 查找子树
// 查找从一个节点出发,到
// 叶子节点结束的所有路径
// 这些路径的集合为一颗子树(子图)
g.V('okram')
    .repeat(out())
    .until(outE().count().is(0))
    .path()
7.3.2、 查找两点之间的最短路径
// 已知两个顶点'okram'和'javeme',
// 通过任意关系来找到这两点之间的路径
// 且限制了最大深度为3
// 若存在那么第一条结果即是最短路径
g.V('okram')
    .repeat(bothE().otherV().simplePath())
    .until(hasId('javeme').and().loops().is(lte(3)))
    .hasId('javeme')
    .path()

注意:bothE().otherV()一般等价于both(),但是在这里有一些差别,后者仅仅返回路径中的顶点信息,前者会把路径中的边信息也返回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值