Почему результат обхода изменяется после пошагового и сохраняет только один результат? - PullRequest
0 голосов
/ 29 января 2019

Я создаю API для извлечения и организации некоторой информации в моей базе данных janusgraph, но я относительно новичок в запросах gremlin.Я хотел бы знать, почему обход второго шага группового шага возвращает некоторую неполную информацию о графе

Запросы отправляются из драйвера python gremlin, как если бы они были запросами gremlin.Сначала я подумал, что проблема связана с этим, но потом я попытался напрямую с терминала gremlin (запускается из bin / gremlin.sh) и результаты были такими же, так что я считаю, что это не ошибка, а какэто должно быть.Это хорошо, но я хотел бы понять, почему запрос приводит к такому и как построить запрос, который соответствует моим потребностям.

В примерах я использую только один шаг для этапа проекта, но вреальная проблема, я намереваюсь использовать несколько пошаговых инструкций, например, так:

(...).project('key1', 'key2', 'key3').by(...).by(...).by(...)

Исходная конфигурация:

gremlin> g.V().has('name', 'fiber')
==>v[1]
==>v[2]

gremlin> g.V(1).in()
==>v[10]

gremlin> g.V(2).in()
==>v[20]


gremlin> g.V().has('name', 'fiber').in()
==>v[10]
==>v[20]

Вот что я получаю:

gremlin> g.V().has('name', 'fiber').group().by('name').by(project('amount').by(__.in().count()))
==>{fiber={amount=1}}

gremlin> g.V().has('name','fiber').group().by('name').by(__.in().count())
==>{fiber=2}

gremlin> g.V().has('name', 'fiber').group().by('name').by(__.in())
==>{fiber=v[20]}

gremlin> g.V().has('name', 'fiber').group().by('name')
==>{fiber=[v[1], v[2]]}

И это то, что я ожидал:

gremlin> g.V().has('name', 'fiber').group().by('name').by(project('amount').by(__.in().count()))
==>{fiber={amount=2}}

gremlin> g.V().has('name','fiber').group().by('name').by(__.in().count())
==>{fiber=2}

gremlin> g.V().has('name', 'fiber').group().by('name').by(__.in())
==>{fiber=[v[10], v[20]]}

gremlin> g.V().has('name', 'fiber').group().by('name')
==>{fiber=[v[1], v[2]]}

1 Ответ

0 голосов
/ 29 января 2019

Как вы видели, это просто выбор дизайна в Gremlin, а не ошибка.Модулятор by() вызывает только next() для анонимного Traversal, переданного в качестве аргумента, и не пытается перебрать всю вещь в списке, если вы явно не укажете это.Я конкретно не помню всех причин, по которым by(Traversal) был создан для такой работы, но в целом я думаю, что для Гремлин безопаснее предположить, что пользователь хочет, чтобы анонимные обходы выполняли как можно меньше работы.Если вы хотите, чтобы это делало больше, вы говорите Гремлин, что хотите, чтобы оно делало больше.

Итак, для этого примера:

g.V().has('name', 'fiber').group().by('name').by(__.in())

если вы хотите, чтобы все вершины in(), вам нужно было бы сказать Гремлину явно собрать это:

g.V().has('name', 'fiber').group().by('name').by(__.in().fold())

Обратите внимание, что by() не единственный шаг, который работает таким образом, и тот факт, что Gremlin делает эту наименьшую возможную работу, на самом деле является удобством, которое может привести к меньшему количеству печатания, как с emit() модулятором для шага repeat():

g.V().repeat(out()).emit(outE())

, который, помимо того, что печатает меньше, читается лучше, чем:

g.V().repeat(out()).emit(outE().limit(1).count().is(1))

Я также думаю, что с by() (и другими шагами / модуляторами, которые принимают Traversal какаргумент), ведя себя так, Гремлин не слишком полагается на то, как вы хотите, чтобы данные выглядели в результате.Если бы Traversal всегда был полностью повторен, это означало бы, что вы всегда получите List в качестве результата, который может или не может быть тем, что вы хотите.Тогда вам останется развернуть и выбросить список - поэтому Гремлин создаст объект, просто чтобы выбросить его в GC.

Возможно, есть и другие причины (в основном более конкретные), почему by() работает так, как он работает, но, надеюсь, это объяснение дает вам некоторое представление о том, почему это так.

...