Ограничение глубины запроса кратчайшего пути с помощью Gremlin на JanusGraph - PullRequest
0 голосов
/ 25 мая 2018

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

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 Ответ

0 голосов
/ 27 июня 2018

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

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

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

...