Gremlin запрос, чтобы получить k вершин расстояния и ребер, соединяющих их - PullRequest
0 голосов
/ 26 июня 2019

Я хочу начать с заданной вершины и получить все связанные вершины и ребра на расстоянии ak.Выходные данные должны включать все ребра, которые соединяют включенные вершины (даже если это ребро находится на расстоянии 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')

https://i.stack.imgur.com/OYEBpm.png

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 edge

С этим запросом

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 вершин расстояния и соединяющих их ребер?

1 Ответ

2 голосов
/ 26 июня 2019

Вы можете интегрировать условие разрыва в свой внутренний повторный обход, что делает его немного легче:

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
...