Gremlin Coalesce для добавления нескольких вершин и ребер

Прямо сейчас я могу сгенерировать запрос, чтобы создать столько вершин и ребер, сколько я хочу.

например

g.V().addV('vert1').as('a').addV('vert2').as('b').addE('has').from('a').to('b')

^^^^^^^^^^^^^ Это работает. Достаточно легко, верно? Теперь давайте создадим запрос gremlin, который создает эти вершины, только если их метка уникальна. Затем создайте грань между ними.

g.V().has(label,'vert1').fold().coalesce(unfold(),addV('vert1')).as('a').V().has(label,'vert2').fold().coalesce(unfold(),addV('vert2')).as('b').addE('has').from('a').to('b')

^^^^^^^^^^^^^ Это не работает

надеюсь, вы понимаете, что я пытаюсь сделать. Может кто-нибудь мне помочь?

Спасибо

2 ответа

Решение

У тебя есть fold() который является ReducingBarrierStep что следует после вашего шага метки на as('a') и история пути к "а" теряется после этого шага. Вы можете прочитать больше об этом аспекте Gremlin здесь.

Вам просто нужно переписать свой запрос, чтобы учесть это - одним из способов может быть просто aggregate() значение "а", а не просто название шага "а":

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.V().
......1>   has(label,'vert1').fold().
......2>   coalesce(unfold(),
......3>            addV('vert1')).aggregate('a').
......4>   V().has(label,'vert2').fold().
......5>   coalesce(unfold(),
......6>            addV('vert2')).as('b').
......7>   select('a').unfold().
......8>   addE('has').to('b')
==>e[2][0-has->1]

Если вам нужно вернуть все элементы, просто project() возвращаемое ребро и трансформируем результаты по мере необходимости:

gremlin> g.V().
......1>   has(label,'vert1').fold().
......2>   coalesce(unfold(),
......3>            addV('vert1')).aggregate('a').
......4>   V().has(label,'vert2').fold().
......5>   coalesce(unfold(),
......6>            addV('vert2')).as('b').
......7>   select('a').unfold().
......8>   addE('has').to('b').
......9>   project('e','in','out').
.....10>     by().
.....11>     by(inV()).
.....12>     by(outV())
==>[e:e[2][0-has->1],in:v[1],out:v[0]]

Конечно, используя select() в конце тоже не все так плохо:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.V().
......1>   has(label,'vert1').fold().
......2>   coalesce(unfold(),
......3>            addV('vert1')).aggregate('a').
......4>   V().has(label,'vert2').fold().
......5>   coalesce(unfold(),
......6>            addV('vert2')).as('b').
......7>   select('a').unfold().
......8>   addE('has').to('b').as('x').
......9>   select('a','b','x')
==>[a:[v[0]],b:v[1],x:e[2][0-has->1]]

Я тоже искал идемпотентный способ создать несколько вершин одной командой и получить результаты обратно. (Я использую API Gremlin Cosmos DB, и типичное решение, использующее складку...объединение...развертывание, не работает при объединении в цепочку.)

Путем некоторых экспериментов я придумал альтернативу, сложность которой линейна по мере добавления новых вершин. я используюinject()искусственно создать «источник» для первого вызоваcoalesce().

      g.inject("0")
  .coalesce(__.V(['pk1','00']), addV('MyV')
    .property('id','00')
    .property('partitionKey','pk1')).as('x')
  .coalesce(__.V(['pk1','01']), addV('MyV')
    .property('id','01')
    .property('partitionKey','pk1'))
    .as('x')
  .coalesce(__.V(['pk1','02']), addV('MyV')
    .property('id','02')
    .property('partitionKey','pk1'))
    .as('x')
.select('x')

Для тех, кого не интересуют ключи разделов, это выглядит так:

      g.inject("0")
  .coalesce(__.V('00'), addV('MyV').property('id','00')).as('x')
  .coalesce(__.V('01'), addV('MyV').property('id','01')).as('x')
  .coalesce(__.V('02'), addV('MyV').property('id','02')).as('x')
.select('x')

Кроме того, мы можем одновременно создавать любое количество ребер между новыми вершинами, предоставляя уникальные метки (сas()).

      g.inject("0")
  .coalesce(__.V(['pk2','05']), addV('MyV').property('id','05')
    .property('partitionKey','pk2')
    .property('ABC','123467890'))
    .as('x').as('a')
  .coalesce(__.V(['pk2','06']), addV('MyV').property('id','06')
    .property('partitionKey','pk2')
    .property('ABC','123467890'))
    .as('x')
  .coalesce(g.E(['pk2','07']), addE('MyE').property('id','07').from('a'))
    .as('x')
.select('x')
Другие вопросы по тегам