На секунду я предположу, что ваш пример - это ваш реальный запрос, и в этом случае вы можете сделать это действительно легко, просто избавившись от обходов ребер следующим образом:
g.V().out().out().path().unfold()
Если ваш примерэто просто упрощенная версия вашего реального обхода, тогда ответ гораздо сложнее.Вот несколько вариантов с учетом «современного» игрушечного графа:
gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().outE().inV().outE().inV().path()
==>[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]
==>[v[1],e[8][1-knows->4],v[4],e[11][4-created->3],v[3]]
Итак, вот вывод из моего первоначального предложения, чтобы мы могли сравнить его с другими вариантами, которые будут использовать outE().inV()
:
gremlin> g.V().out().out().path().unfold()
==>v[1]
==>v[4]
==>v[5]
==>v[1]
==>v[4]
==>v[3]
Полагаю, вы могли бы пометить свои шаги, а затем select()
все их:
gremlin> g.V().as('a').outE().inV().as('a').outE().inV().as('a').select(all,'a').unfold()
==>v[1]
==>v[4]
==>v[5]
==>v[1]
==>v[4]
==>v[3]
Я бы хотел вообще избегать меток шагов, если это возможно, хотя один из способов отфильтровать элементы смешанного графика - этовыбрать фильтр, который может однозначно идентифицировать их.Например, в современном графе я знаю, что список меток вершин и ребер глобально уникален (нет метки вершин, совпадающей с меткой ребра), поэтому я могу просто сделать:
gremlin> g.V().outE().inV().outE().inV().path().unfold().hasLabel('person','software')
==>v[1]
==>v[4]
==>v[5]
==>v[1]
==>v[4]
==>v[3]
Вы можете делать подобные трюки с has()
, если у вас есть ключ или значение свойства с уникальным именем.Если у вас нет ничего из этого, то вы можете застрять с помощью лямбды, которая не так хороша:
gremlin> g.V().outE().inV().outE().inV().path().unfold().filter{it.get() instanceof Vertex}
==>v[1]
==>v[4]
==>v[5]
==>v[1]
==>v[4]
==>v[3]