问题
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
Points
vertex with the lowesttotalPoints
value. - Sum the
totalPoints
with the new number of points. - If the sum exceeds 500, set the
totalPoints
property value to 500 and add a newPoints
vertex with atotalPoints
value ofsum-500
. - If the sum doesn't exceed 500, set it as the new
totalPoints
property 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