Я изучаю графовые базы данных, создавая простую сеть MLM (по сути, пользователь может спонсировать другого пользователя, и у всех пользователей не более одного спонсора). Я хочу выполнить запрос, который:
- Go от выбранного пользователя к другому пользователю, пока не будет удовлетворен определенный предикат, - затем суммируйте точки всех пользователей вдоль выбранных путей в значение ( это значение должно быть дедуплировано для предотвращения двойного счета, когда пользователь разветвляется на нескольких пользователей.
- Повторите этот шаг 3 раза, но каждый раз начинайте с последнего пользователя, который был достигнут на предыдущем шаге.
- Вывести суммы в виде списка.
Я пробовал следующий запрос:
g.V(userID)
.repeat(
repeat(out('sponsors')
.until(somePredicate)
.out('hasPoints')
.as('level') // How do I know the current loop iteration so I can store level1/level2/level3 in as step dynamically?
// This is where I'm stuck, since I have no idea how to capture and sum all the points in this subtree.
.in('hasPoints')
)
.times(3)
// Also need to output the point sums as a list/map here, e.g. ["level1": 100, "level2": 100],
// "level1" being the first iteration of repeat and so on.
Любой указатель?
РЕДАКТИРОВАТЬ:
Вот сценарий Gremlin для примеров данных:
g.addV('user').property('id', 1).as('1')
addV('user').property('id', 2).as('2').
addV('user').property('id', 3).as('3').
addV('user').property('id', 4).as('4').
addV('user').property('id', 5).as('5').
addV('user').property('id', 6).as('6').
addV('user').property('id', 7).as('7').
addV('point').property('value', 5).as('p1')
addV('point').property('value', 5).as('p2').
addV('point').property('value', 5).as('p3').
addV('point').property('value', 5).as('p4').
addV('point').property('value', 5).as('p5').
addV('point').property('value', 5).as('p6').
addV('point').property('value', 5).as('p7').
addE('sponsors').from('1').to('2').
addE('sponsors').from('1').to('3').
addE('sponsors').from('1').to('4').
addE('sponsors').from('2').to('5').
addE('sponsors').from('3').to('6').
addE('sponsors').from('4').to('7').
addE('hasPoints').from('1').to('p1').
addE('hasPoints').from('2').to('p2').
addE('hasPoints').from('3').to('p3').
addE('hasPoints').from('4').to('p4').
addE('hasPoints').from('5').to('p5').
addE('hasPoints').from('6').to('p6').
addE('hasPoints').from('7').to('p7').
iterate()
Это запрос, который я пишу для группировки уровней вместе на основе некоторого предиката:
g.V()
.has('id', 1)
.repeat('x',
identity()
.repeat(
out('sponsors')
.choose(loops('x'))
.option(0, identity().as('a1'))
.option(1, identity().as('a2'))
.option(2, identity().as('a3'))
)
.until(or(out('hasPoints').has('value', gte(5))))
.sideEffect(
choose(loops('x'))
.option(0, select(all, 'a1'))
.option(1, select(all, 'a2'))
.option(2, select(all, 'a3'))
.unfold()
.choose(loops('x'))
.option(0, store('b1'))
.option(1, store('b2'))
.option(2, store('b3'))
)
)
.times(3)
.cap('b1', 'b2', 'b3')
Несмотря на то, что я могу вручную установить переменные и выбрать правильные переменные, я пока не знаю, как это сделать динамически - т. Е. Вместо times(3)
может возникнуть ситуация, когда мне нужно, чтобы она была until
, поэтому счетчик итераций больше не известен eforehand.