首页 > 解决方案 > 使用 Gremlin (AWS Neptune),如何从具有特定条件的起始节点遍历边缘获取长度为 n 的所有路径?

问题描述

从节点 1 开始,我想在任何出站边之后的 n 个跃点内返回所有路径(边和顶点,带有 id/label/properties),或者在带有属性谓词(p > 50)的入站边之后返回。

理想情况下,路径不应包含任何循环,因此路径不应包含两次相同的节点。

属性 p 并不存在于每条边上。

g.addV().property(id, 1).as('1').
  addV().property(id, 2).as('2').
  addV().property(id, 3).as('3').
  addV().property(id, 4).as('4').
  addV().property(id, 5).as('5').
  addV().property(id, 6).as('6').
  addV().property(id, 7).as('7').
  addV().property(id, 8).as('8').
  addE('pointsAt').from('1').to('2').
  addE('pointsAt').from('3').to('1').
  addE('pointsAt').from('4').to('1').property('p', 10).
  addE('pointsAt').from('5').to('1').property('p', 100).
  addE('pointsAt').from('2').to('6').
  addE('pointsAt').from('7').to('2').
  addE('pointsAt').from('8').to('2').property('p', 100).
  iterate()

假设我们从顶点 1 开始,路径将如下所示:

1>2
1>2>6
1>2>8
1>5

我已经尝试了许多不同的方法,但我似乎无法得到任何接近我正在寻找的东西。

标签: gremlintinkerpopamazon-neptune

解决方案


我相信这就是您正在寻找的:

g.V(1).
   repeat(
      union(
         outE(),inE().has('p',gt(50))
      ).
      otherV().simplePath()).
   emit().
   times(2).
   path().
      by(valueMap().with(WithOptions.tokens))

repeat() 和 times() 步骤表明这是一个深度为 2 的递归遍历。 union() 步骤和包含参数遵循您的要求,包括所有传出边和仅 ap 属性大于 50 的传入边。 emit() 步骤强制 repeat() 步骤在找到所有路径时对其进行流式传输。如果你不包括这个,你只会得到长度为 2 的路径(在 times() 步骤中声明)。

总结一下,我们使用 path() 和 by() 来输出找到的路径以及路径中每个顶点和边的所有 id、标签和属性。

您提供的图表的输出如下所示:

==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex]]
==>[[id:1,label:vertex],[id:3,label:pointsAt,p:100],[id:5,label:vertex]]
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex],[id:4,label:pointsAt],[id:6,label:vertex]]
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex],[id:6,label:pointsAt,p:100],[id:8,label:vertex]]

推荐阅读