Суммируйте информацию о пути в Gremlin с помощью project () и select (). - PullRequest
0 голосов
/ 13 марта 2019

Я пытаюсь написать запрос 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([])
))

Что бы я хотелsee - это идентификатор каждого листа с массивом идентификаторов его «известных» предков:

[
    {
        "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 Ответ

1 голос
/ 13 марта 2019

Я думаю, вы можете немного упростить.Прежде всего обратите внимание, что 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» `.

...