Ограничение глубины запроса кратчайшего пути с помощью Gremlin на JanusGraph

У меня довольно большой график (в настоящее время 3806702 вершин и 7774654 ребер, все ребра с одинаковой меткой) в JanusGraph. Я заинтересован в поисках кратчайшего пути в нем. Рецепты Гремлин упоминают этот запрос:

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() в одном и том же запросе всегда происходит сбой с NullPointerException в классах обхода gremlin, т.е.

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)
...

У кого-нибудь есть идеи, как я могу применить такой лимит? Мне нужно это, чтобы вернуть первый результат или потерпеть неудачу, быстро.

Спасибо!

1 ответ

Добавьте еще одно условие перерыва в вашем until() а также убедитесь, что limit() результат, прежде чем вы спросите пути:

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

призвание tryNext() на этом обходе даст вам Optional<Path>, Если он пуст, то в пределах заданного расстояния пути не найдено.

Другие вопросы по тегам