首页 > 解决方案 > 在 JanusGraph 上使用 Gremlin 限制最短路径查询的深度

问题描述

我在 JanusGraph 中有一个相当大的图(目前有 3806702 个顶点和 7774654 条边,所有边都具有相同的标签)。我对其中的最短路径搜索感兴趣。Gremlin recipes 提到了这个查询:

g.V(startId).until(hasId(targetId)).repeat(out().simplePath()).path().limit(1)

这会立即返回我知道是正确路径的路径,但随后会挂起控制台(top虽然显示 janusgraph 和 scylla 正在疯狂地处理东西,所以我猜它正在后台工作,但它需要永远)。如果像这样使用它,它会做正确的事情并返回第一个(正确的)最短路径:

g.V(startId).until(hasId(targetId)).repeat(out().simplePath()).path().next()

我想限制这个查询,以便 gremlin/janusgraph 停止搜索路径,比如说 100 跳(所以我基​​本上想要 100 个边缘的最大深度)。我曾尝试.times(100)在多个位置使用,但如果在同一个查询.until()中使用,.times()它总是在 gremlin 遍历类中以 NullPointerException 崩溃,即:

java.lang.NullPointerException
        at org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper.hasStepOfAssignableClassRecursively(TraversalHelper.java:351)
        at org.apache.tinkerpop.gremlin.process.traversal.strategy.optimization.RepeatUnrollStrategy.apply(RepeatUnrollStrategy.java:61)
        at org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversalStrategies.applyStrategies(DefaultTraversalStrategies.java:86)
        at org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal.applyStrategies(DefaultTraversal.java:119)
        at org.apache.tinkerpop.gremlin.process.traversal.util.DefaultTraversal.next(DefaultTraversal.java:198)
        at java_util_Iterator$next.call(Unknown Source)
...

有谁知道我该如何应用这样的限制?我需要这个来快速返回第一个结果或失败。

谢谢!

标签: graphgremlinshortest-pathtinkerpopjanusgraph

解决方案


在您的中添加另一个中断条件,并在您询问路径之前until()确保结果:limit()

g.V(startId).
  until(__.hasId(targetId).or().loops().is(100)).
    repeat(__.both().simplePath()).
  hasId(targetId).limit(1).path()

调用tryNext()这个遍历会给你一个Optional<Path>. 如果它是空的,那么在给定的距离内没有找到路径。


推荐阅读