Gremlin 查询获取 k 个距离顶点和连接它们的边

Gremlin query to get k distance vertices and edges connecting them

我想从给定的顶点开始,将所有连接的顶点和边连接到一个 k 距离内。 输出应该包括连接包含的顶点的所有边(即使该边在 k+1 距离处)以便我们有一个完整的子图。

假设我们有这个:

g.addV('person').property('name', 'a').as('va')
 .addV('person').property('name', 'b').as('vb')
 .addV('person').property('name', 'c').as('vc')
 .addV('person').property('name', 'd').as('vd')
 .addV('person').property('name', 'e').as('ve')
 .addV('person').property('name', 'f').as('vf')
 .addV('person').property('name', 'g').as('vg')
 .select('va').addE('knows').to('vb')
 .select('vb').addE('knows').to('vc')
 .select('vc').addE('knows').to('vd')
 .select('vd').addE('knows').to('ve')
 .select('ve').addE('knows').to('va')
 .select('ve').addE('knows').to('vf')
 .select('vf').addE('knows').to('vg')

a->b->c->d->e->(a)e->f->g

如果我们从 c 开始,距离为 2,我们应该

a->b->c->d->e->(a)

有了这个查询

g.V().has('person','name','c')
     .repeat(bothE().dedup()
                    .store("e")
                    .bothV()
                    .dedup()
                    .store("v"))
     .times(2)
     .cap('e','v')

我可以得到 a->b->c->d->e 但我们失去了 e->a 优势

有了这个查询

g.V().has('person','name','c')
     .repeat(bothE().dedup()
                    .store("e")
                    .bothV()
                    .dedup()
                    .store("v"))
     .times(2)
     .bothE()
     .dedup()
     .store('e')
     .cap('e','v')

我们得到了连接外部顶点的额外边,但我们也得到了连接外部顶点的边 f 我们得到 a->b->c->d->e->(a) 但也得到 e->f

如何才能只得到k距离的顶点和连接它们的边?

您可以将中断条件集成到您的内部 repeat-traversal,这样会更容易一些:

g.V().has('person','name','c').store('v').
  repeat(bothE().where(without('e')).
         choose(loops().is(lt(2)),
                  aggregate('e'),
                  filter(otherV().where(within('v'))).aggregate('e').not(identity())).
         otherV().where(without('v')).aggregate('v')).
  cap('e','v')

在您的示例图表上:

gremlin> g.V().has('person','name','c').store('v').
......1>   repeat(bothE().where(without('e')).
......2>          choose(loops().is(lt(2)),
......3>                   aggregate('e'),
......4>                   filter(otherV().where(within('v'))).aggregate('e').
......5>                   not(identity())).
......6>          otherV().where(without('v')).aggregate('v')).
......7>   cap('e','v').sideEffect {
......8>      m = it.get()
......9>      println 'Vertices:'
.....10>      m.get('v').each {
.....11>        println "* " + it.value('name')
.....12>      }
.....13>      println 'Edges:'
.....14>      m.get('e').each {
.....15>        println "* " + [it.outVertex(), it.inVertex()]*.value('name').join(' -> ')
.....16>      }
.....17>   }.iterate()
Vertices:
* c
* d
* b
* e
* a
Edges:
* c -> d
* b -> c
* d -> e
* a -> b
* e -> a