Вычислить связь между последовательными вершинами на пути - PullRequest
0 голосов
/ 10 июня 2019

Дано графическое изображение, как показано ниже:

subgraph

Найдите все пути между person1 и person5, затем вычислите связь между последовательными вершинами на пути.

Чтобы проиллюстрировать определение connection, возьмем person1 и person2 в качестве примера:
1. person1 создать comment1 для ответа post2 создатель person2
2. person2 создать comment3 для ответа post1 создатель person1

Итак, связь между person1 и person2 равна 2; и что между person2 и person5 равно 0.

Путь на приведенном выше графике: [v[person1],v[person2],v[person5]]:

gremlin> g.V('person1').
......1>   repeat(both('knows').simplePath()).
......2>     until(hasId('person5')).path()
==>[v[person1],v[person2],v[person5]]

Пока я могу получить только dsl:

gremlin> g.V('person1').
......1>   repeat(both('knows').simplePath()).
......2>     until(hasId('person5').or().loops().is(eq(2))).hasId('person5').path().
......3>       repeat(
......4>         filter(count(local).is(gt(1))).
......5>           sack(assign).by(
......6>             sideEffect(range(local,1,2).aggregate('m')).
......7>             range(local,0,1).
......8>             in('hasCreator').hasLabel('comment').
......9>             out('replyOf').hasLabel('post').
.....10>             out('hasCreator').where(within('m')).count()
.....11>           ).
.....12>           sack(sum).by(
.....13>             sideEffect(range(local,0,1).aggregate('n')).
.....14>             range(local,1,2).
.....15>             in('hasCreator').hasLabel('comment').
.....16>             out('replyOf').hasLabel('post').
.....17>             out('hasCreator').where(within('n')).count()
.....18>           ).
.....19>           skip(local, 1)
.....20>         ).
.....21>       emit().sack().fold()
==>[2,1]

Но результат неправильный, который, как ожидается, будет [2,0]. Я знаю, что не должен использовать aggregate для фильтрации, но я не могу найти подходящий метод в соответствии с моими знаниями.

Пример графика может быть сгенерирован:

g.addV('person').property(id, 'person1')
g.addV('person').property(id, 'person2')
g.addV('person').property(id, 'person5')

g.addE('knows').from(V('person1')).to(V('person2'))
g.addE('knows').from(V('person2')).to(V('person5'))

g.addV('post').property(id, 'post1')
g.addV('post').property(id, 'post2')

g.addV('comment').property(id, 'comment1')
g.addV('comment').property(id, 'comment2')
g.addV('comment').property(id, 'comment3')

g.addE('hasCreator').from(V('post1')).to(V('person1'))
g.addE('hasCreator').from(V('post2')).to(V('person2'))

g.addE('hasCreator').from(V('comment1')).to(V('person1'))
g.addE('hasCreator').from(V('comment2')).to(V('person2'))
g.addE('hasCreator').from(V('comment3')).to(V('person2'))

g.addE('replyOf').from(V('comment1')).to(V('post2'))
g.addE('replyOf').from(V('comment2')).to(V('post2'))
g.addE('replyOf').from(V('comment3')).to(V('post1'))

1 Ответ

0 голосов
/ 11 июня 2019

После того, как я заменил использование aggregate на select, я могу получить правильный ответ:

g.V('person1').
  repeat(both('knows').simplePath()).
    until(hasId('person5').or().loops().is(eq(2))).hasId('person5').path().
        repeat(
            filter(count(local).is(gt(1))).
                sack(assign).by(
                  __.as('orig').
                  range(local,1,2).as('v2').
                  select('orig').range(local,0,1).
                    in('hasCreator').hasLabel('comment').
                    out('replyOf').hasLabel('post').
                    out('hasCreator').where(eq('v2')).count()
                ).
                sack(sum).by(
                  __.as('orig').
                  range(local,0,1).as('v1').
                  select('orig').range(local,1,2).
                    in('hasCreator').hasLabel('comment').
                    out('replyOf').hasLabel('post').
                    out('hasCreator').where(eq('v1')).count()
                ).
                skip(local, 1)
            ).
        emit().sack().fold()
...