Суммируйте информацию о пути в Gremlin с помощью project() и select().
Я пытаюсь написать запрос Gremlin, который будет проходить через несколько вершин и возвращать листья вместе с некоторой информацией о пути, по которому он прошел.
Проще всего объяснить на примере:
# Sample graph diagram
# 1 --> 2* --> 3* --> 4
# \ \---> 5* --> 6
# \-> 7
# Create sample graph
g.addV('V').as('1').property('id','1').property('notable',false)
.addV('V').as('2').property('id','2').property('notable',true)
.addE('E').from('1')
.addV('V').as('3').property('id','3').property('notable',true)
.addE('E').from('2')
.addV('V').as('4').property('id','4').property('notable',false)
.addE('E').from('3')
.addV('V').as('5').property('id','5').property('notable',true)
.addE('E').from('2')
.addV('V').as('6').property('id','6').property('notable',false)
.addE('E').from('5')
.addV('V').as('7').property('id','7').property('notable',false)
.addE('E').from('1')
Следующий обход начинается с вершины 1 и продолжается out()
насколько это возможно, собирая "известные" вершины, используя as()
,
g.V('1')
.out()
.until(out().count().is(0))
.repeat(
optional(has('notable', true).as("notables"))
.out()
)
.project('Id','NotableAncestors')
.by(id())
.by(coalesce(
select('notables').unfold().id(), inject([])
))
То, что я хотел бы видеть, является идентификатором каждого листа с массивом идентификаторов его "известных" предков:
[
{
"Id": "7",
"NotableAncestors": []
},
{
"Id": "4",
"NotableAncestors": ["2", "3"]
},
{
"Id": "6",
"NotableAncestors": ["2", "5"]
}
]
Но вместо NotableAncestors
будучи массивом, я получаю только первое значение, потому что unfold()
Выровняйте массив только до первого элемента в нем, как вы можете видеть ниже. Альтернативно, если я пропущу unfold()
Я получаю массив, но он всегда пуст.
[
{
"Id": "7",
"NotableAncestors": []
},
{
"Id": "4",
"NotableAncestors": "2"
},
{
"Id": "6",
"NotableAncestors": "2"
}
]
1 ответ
Я думаю, вы можете немного упростить. Первое замечание, что as()
это метка шага, на которую вы можете сослаться, чтобы проверить, что находится на этом шаге в определенной точке обхода, так что на самом деле это не "сбор" вещей. Вот еще один путь:
gremlin> g.V('1').
......1> repeat(out()).
......2> emit(outE().count().is(0)).
......3> project('Id','NotableAncestors').
......4> by(id()).
......5> by(path().unfold().has('notable',true).id().fold())
==>[Id:7,NotableAncestors:[]]
==>[Id:4,NotableAncestors:[2,3]]
==>[Id:6,NotableAncestors:[2,5]]
Я удалил кучу лишних шагов и просто прошел out()
несколько раз от вершины "1", испуская только вершины листа, которые вам нужны. Затем я просто анализирую path()
принято, чтобы добраться до этого листа для любых "заметных" вершин и добавить сложить их в List
для "NotableAncestors".