问题
Sample data:
I have two vertices by names User , Points
First adding data for vertex User
g.addV('User').property('id',1).
addV('User').property('id',2).
addV('User').property('id',3).iterate()
Now adding Points vertices and connecting addingPoints Edge from User to Points
g.V().hasLabel('User').has('id',1).as('curUser1').
V().hasLabel('User').has('id',2).as('curUser2').
V().hasLabel('User').has('id',3).as('curUser3').
addV('Points').property('totalPoints',0).property('userPoints',0).
property('createDate',1560316666).property('name','user1').
addE('addingPoints').from('curUser1').
addV('Points').property('totalPoints',0).property('userPoints',0).
property('createDate',1560318666).property('name','user2').
addE('addingPoints').from('curUser2').
addV('Points').property('totalPoints',0).property('userPoints',0).
property('createDate',1560318657).property('name','user3').
addE('addingPoints').from('curUser3').iterate()
Now each User is having atleast one Points vertex.
Now I want to add 10 (or) 20 (or) 30 points randomly to totalPoints Property of user with id as 1
while adding the points, I have three cases:
1.If totalPoints are lt500 Then I just need to update the totalPoints property of Points vertex of user with id as 1.
2.If totalPoints are eq500 Then I should create new Points vertex and add points to totalPoints property of Points vertex of user with id as 1.
3.If totalPoints are 490 which is not eq500 but lt500. But now if I need to add 30 points to the totalPoints property then I need to add 10 points to the old Points vertex of user with id as 1 and I should add remaining 20 points to new Points vertex of user with id as 1.
How can I achieve this.
Thank you.
回答1:
- Pick the user's
Pointsvertex with the lowesttotalPointsvalue. - Sum the
totalPointswith the new number of points. - If the sum exceeds 500, set the
totalPointsproperty value to 500 and add a newPointsvertex with atotalPointsvalue ofsum-500. - If the sum doesn't exceed 500, set it as the new
totalPointsproperty value.
These 4 steps translated into a traversal:
g.withSack(points).
V().has('User','id',user).as('u').
out('addingPoints').
order().
by('totalPoints').
limit(1).
sack(sum).
by('totalPoints').
choose(sack().is(gt(maxPoints)),
sack(minus).
by(constant(maxPoints)).
property('totalPoints', maxPoints).
addV('Points').
sideEffect(addE('addingPoints').
from('u'))).
property('totalPoints', sack())
And a small console example (I initialized the first Points vertex with totalPoints=400 and the second Points vertex with totalPoints=480):
gremlin> showUserPoints = {
......1> g.V().as('u').out('addingPoints').
......2> group().
......3> by(select('u').by('id')).
......4> by('totalPoints').next()
......5> }
==>groovysh_evaluate$_run_closure1@7c2b58c0
gremlin> addPoints = { user, points, maxPoints = 500 ->
......1> g.withSack(points).
......2> V().has('User','id',user).as('u').
......3> out('addingPoints').
......4> order().
......5> by('totalPoints').
......6> limit(1).
......7> sack(sum).
......8> by('totalPoints').
......9> choose(sack().is(gt(maxPoints)),
.....10> sack(minus).
.....11> by(constant(maxPoints)).
.....12> property('totalPoints', maxPoints).
.....13> addV('Points').
.....14> sideEffect(addE('addingPoints').
.....15> from('u'))).
.....16> property('totalPoints', sack()).iterate()
.....17>
.....17> showUserPoints()
.....18> }
==>groovysh_evaluate$_run_closure1@31d6f3fe
gremlin> showUserPoints()
==>1=[400]
==>2=[480]
==>3=[0]
gremlin> addPoints(1, 10)
==>1=[410]
==>2=[480]
==>3=[0]
gremlin> addPoints(1, 90)
==>1=[500]
==>2=[480]
==>3=[0]
gremlin> addPoints(2, 30)
==>1=[500]
==>2=[500, 10]
==>3=[0]
gremlin> addPoints(2, 40)
==>1=[500]
==>2=[500, 50]
==>3=[0]
gremlin> addPoints(3, 100)
==>1=[500]
==>2=[500, 50]
==>3=[100]
来源:https://stackoverflow.com/questions/56580992/gremlin-adding-new-vertex-if-it-exceeds-the-limit