Как вы видели, это просто выбор дизайна в 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()
работает так, как он работает, но, надеюсь, это объяснение дает вам некоторое представление о том, почему это так.