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
我想从给定的顶点开始,将所有连接的顶点和边连接到一个 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