Gremlin - одновременное ограничение итераций обхода и поиск свойства ребра
У меня есть (сломанный) фрагмент кода гремлина для создания кратчайшего пути от заданной вершины к той, которая имеет параметр test_parameter
. Если этот параметр не найден на краю, пути не должны возвращаться.
s.V(377524408).repeat(bothE().has('date', between(1554076800, 1556668800)).otherV()) /* date filter on edges */
.until(or(__.bothE().has('test_property', gt(0)),
loops().is(4))) /* broken logic! */
.path()
.local(unfold().filter(__.has('entity_id')).fold()) /* remove edges from output paths*/
Разорванная линия .until(or(__.outE().has('test_property', gt(0)), loops().is(4)))
.
В настоящее время - и это понятно почему - он дает все пути, которые находятся в 4 шагах от начальной вершины.
Я пытаюсь адаптировать его так, чтобы если ход был на 4 итерациях, и если свойство test_property
это не найден, то он не должен возвращать любые пути. Еслиtest_property
найден, он должен возвращать только путь (пути) к этой вершине.
Я попытался поставить times(4)
ограничение и снятие loops()
состояние, но не знаю, как times(4)
это и .has('test_property', gt(0))
ограничение.
2 ответа
Ответ Даниэля имеет несколько проблем (см. Комментарии). Этот запрос возвращает правильный результат:
g.V(377524408)
.repeat(bothE().has('date', between(1554076800, 1556668800)).otherV().simplePath().as("v"))
.until(and(bothE().has('tp', gt(0)), loops().is(lte(4))))
.select(all, "v")
.limit(1)
В simplePath()
требуется, поэтому мы не будем ходить туда-сюда и избегать кругов.
Цикл повторения длится до тех пор, пока условие не будет выполнено И мы не достигнем максимального скачка.
В limit(1)
вернуть только первый (кратчайший) путь. Пропустите все пути.
Обратите внимание, что если график ориентирован, лучше использовать outE()
и нет bothE()
.
Это должно работать:
s.V(377524408).
repeat(bothE().has('date', between(1554076800, 1556668800)).otherV().as('v')).
times(4).
filter(bothE().has('test_property', gt(0))).
select(all, 'v')
Также обратите внимание, что я заменил ваш local(unfold().filter(__.has('entity_id')).fold())
с чем-то гораздо более простым (при условии, что единственной целью было удаление ребер с пути).