Агрегация значений вдоль обхода Gremlin Cosmos DB - PullRequest
0 голосов
/ 04 июля 2018

Мне нужно выполнить запрос в следующей форме: у меня есть древовидная структура с затратами на конечном узле. Мне нужен один запрос, чтобы получить все совокупные затраты под корневым узлом. enter image description here

Например, на приведенном выше графике я бы ожидал вывод из моего запроса, например

{ 1: 6, 2: 4, 3: 2, 4: 1, 5: 1, 6: 2, 7: 1, 8: 1}

Я искал для этого шаг 'sack' из Gremlin API, но в настоящее время cosmosDB, похоже, не поддерживает мешки. Я также попытался сохранить псевдо-свойство «агрегатной стоимости» и пробиться вверх от конечных узлов, но не смог выяснить, как хранить динамическое значение на каждом узле как свойство, локальное только для этого узла. , Возможен ли такой тип запроса с учетом этих ограничений?

1 Ответ

0 голосов
/ 04 июля 2018

Когда вы задаете вопросы о Gremlin, всегда лучше включить короткий сценарий Gremlin с примерами данных:

g.addV().property('id',1).as('1').
  addV().property('id',2).as('2').
  addV().property('id',3).as('3').
  addV().property('id',4).property('cost',1).as('4').
  addV().property('id',5).property('cost',1).as('5').
  addV().property('id',6).property('cost',2).as('6').
  addV().property('id',7).property('cost',1).as('7').
  addV().property('id',8).property('cost',1).as('8').
  addE('link').from('1').to('2').
  addE('link').from('1').to('3').
  addE('link').from('2').to('4').
  addE('link').from('2').to('5').
  addE('link').from('2').to('6').
  addE('link').from('3').to('7').
  addE('link').from('3').to('8').iterate()

С помощью шагов, доступных в CosmosDB, я думаю, что самое близкое, что вы могли бы получить, это:

gremlin> g.V().
......1>   group().
......2>     by('id').
......3>     by(emit(has('cost')).
......4>        repeat(out()).
......5>        values('cost').
......6>        fold())
==>[1:[1,1,2,1,1],2:[1,1,2],3:[1,1],4:[1],5:[1],6:[2],7:[1],8:[1]]

group() помогает создать желаемую структуру Map. Затем для каждой вершины, которую вы группируете, используйте repeat(), чтобы пройти до тех пор, пока не достигнете листовых вершин. Обратите внимание, что emit() гарантирует, что только те вершины, которые являются листьями со свойством "cost", возвращаются для цели результата.

Причина, по которой я говорю, что это настолько близко, насколько это возможно с CosmosDB, заключается в том, что я не вижу, чтобы CosmosDB поддерживал sum() step здесь . Если это так, то:

gremlin> g.V().
......1>   group().
......2>     by('id').
......3>     by(emit(has('cost')).
......4>        repeat(out()).
......5>        values('cost').
......6>        sum())
==>[1:6,2:4,3:2,4:1,5:1,6:2,7:1,8:1]

Полагаю, вам придется выполнить это окончательное вычисление для возвращаемого результата самостоятельно.

Для других (или когда CosmosDB поддерживает sack() в будущем) вы можете сделать:

gremlin> g.V().has('cost').
......1>   sack(assign).
......2>     by('cost').
......3>   emit().
......4>     repeat(__.in('link')).
......5>   group().
......6>     by('id').
......7>     by(sack().sum())
==>[1:6,2:4,3:2,4:1,5:1,6:2,7:1,8:1]

Предоставлено Гремлин Гремлин .

...