计算路径上连续顶点之间的连接

时间:2019-06-10 05:42:43

标签: gremlin

给出如下图所示的图形:

subgraph

找到person1person5之间的所有路径,然后计算路径上连续顶点之间的连接。

要说明connection的定义,请以person1person2为例:
1. person1创建comment1来回复post2创建的person2
2. person2创建comment3来回复post1创建的person1

因此,person1person2之间的连接为2;在person2person5之间是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 :(得分:0)

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()