【问题标题】:Using Gremlin (AWS Neptune), how can I get all paths of length n from a starting node traversing edges with specific criteria?使用 Gremlin (AWS Neptune),如何从具有特定条件的起始节点遍历边缘获取长度为 n 的所有路径?
【发布时间】:2020-08-07 23:56:49
【问题描述】:

从节点 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
  • 1-2 被包含,因为它是出站的
  • 1-3 被排除在外,因为它是入站到 1 并且没有 p
  • 1-4 被排除,因为它是入站且 (p > 50) 为假
  • 1-5 被包含,因为它是入站的并且 (p > 50) 为真
  • 2-6 被包含,因为它是出站的
  • 2-7 被排除在外,因为它是入站到 2 并且没有 p
  • 2-8 被包含,因为它是入站到 2 并且 p > 50

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

【问题讨论】:

    标签: gremlin tinkerpop amazon-neptune


    【解决方案1】:

    我相信这就是您要找的:

    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() 步骤和包含参数遵循您的要求,包括所有传出边,并且只包含 p 属性更大的传入边大于 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]]
    

    【讨论】:

    • 感谢您的回答,这真的很接近我的需要。如何获得包含 inV 和 outV 的边缘?看起来海王星不支持 elementMap()。我尝试过尝试将 valueMap() 与 project() 结合,但我做错了。 ....times(maxHops).path().by(union(valueMap().with(WithOptions.tokens),project("outV", "inV").by(outV().id()).by(inV().id()).unfold()));
    • 看来我可以 union(project(), valueMap()) 来获取 gremlin 控制台中每条边的顶点 id,它可以工作。尝试在 java 中做同样的事情会出错,因为 project() 和 valueMap() 结果的泛型不一样。
    • 在 Kelvin 关于 Gremlin (Practical Gremlin) 的书中,他有一节讨论 elementMap 以及使用早期版本的 TinkerPop 生成类似 elementMap 的输出的另一种方法 - kelvinlawrence.net/book/Gremlin-Graph-Guide.html#element-map。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2015-04-19
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多