0
votes

I have a "User" vertex having few users in it. I have an "Invitation" vertex which basically tells about an invitation a user has sent to another user. I have a "sentTo" edge connecting Invitation vertex with the user vertex(the user who is the recipient of the invitation). I have a "sentBy" edge connecting the Invitation vertex to the user vertex(the user who has sent the invitation). The sentBy edge has a "on" property which is a Date object. The sentBy edge also has "inviterCount" property, which is basically the invitation count(at that time of creation of sentBy edge) for that recipient user(the user who receives the invitations). For some reason I have the "on" property correctly set, but not the inviterCount. In order to set the inviterCount on a sentBy edge I need to first order the invitations sent to that user. I am able to order the sentBy edges by "on" date in ascending order which is a fairly straightforward gremlin query. I am struggling to update the inviterCount property which is basically the position of that user in the list of invitations. How do I know the position of an edge in a list of edges, and also set a property on that edge (inviterCount) within a query, for a given recipient of invitations?

g.addV('User').property('userId',1).property('name','Sam').as('u1')
.addV('User').property('userId',2).property('name','Ram').as('u2')
.addV('User').property('userId',3).property('name','Cam').as('u3')
.addV('User').property('userId',4).property('name','Nam').as('u4')
.addV('Invitation').property('invitationId',1).as('i1')
.addE('sentBy').property('on',new Date(1621047481204)).to('u1')
.select('i1').addE('sentTo').to('u4')
.addV('Invitation').property('invitationId',2).as('i2')
.addE('sentBy').property('on',new Date(1621047612262)).to('u2')
.select('i2').addE('sentTo').to('u4')
.addV('Invitation').property('invitationId',3).as('i3')
.addE('sentBy').property('on',new Date(1621047644430)).to('u3')
.select('i3').addE('sentTo').to('u4') 

g.V().hasLabel('User').has('name','Nam').inE('sentTo').outV().outE('sentBy').order().by('on')

As I have stated earlier the sentBy edge has another property called inviterCount which needs to be set.

Edit I have read through sacks, but they don't help with what I need to do. For each traversal, the sack variable is reset and any operations on that sack will be carried across for that traversal. What I need is a counter which carries across traversals. In simpler words, I need an iteration counter. I need an 'i' in the basic for loop.

1
It would be helpful if you could add to your question some Gremlin steps that create a small sample graph. This will help people test any answers they are able to provide. An example of creating a sample graph can be found here stackoverflow.com/questions/66863052/… - Kelvin Lawrence
@KelvinLawrence as asked I have added a sample graph. - Siva Bathula
Just checking one more thing, in the query you provided, you showed inE('sentBy') and Nam, but in the data all of the edges connecting to Nam are of the form inE('sentTo'). If I understand your explanation you may be able to use the index step. I can try to provide an example if you can clarify the way the edge labels and the query are supposed to be. - Kelvin Lawrence
@KelvinLawrence Sorry about that. I have modified the query. What is the index step? Is this the one? kelvinlawrence.net/book/PracticalGremlin.html#tp34index - Siva Bathula
Yes that's the one. I have added an answer below based on my understanding of what you need. - Kelvin Lawrence

1 Answers

2
votes

The index step can be used to simulate your i is the index requirement as follows. If you need to then do something with those values then you can use a tail step to get the index for each edge.

gremlin> g.V().hasLabel('User').
......1>       has('name','Nam').
......2>       inE('sentTo').
......3>       outV().
......4>       outE('sentBy').
......5>       order().
......6>         by('on').
......7>       fold().
......8>       index().
......9>       unfold()  

==>[e[60896][60894-sentBy->60882],0]
==>[e[60900][60898-sentBy->60885],1]
==>[e[60904][60902-sentBy->60888],2]  

The query can be extended to create properties on the edges that use the index.

gremlin> g.V().hasLabel('User').
......1>       has('name','Nam').
......2>       inE('sentTo').
......3>       outV().
......4>       outE('sentBy').
......5>       order().
......6>         by('on').
......7>       fold().
......8>       index().
......9>       unfold().as('edges').
.....10>       limit(local,1).
.....11>       property('i',select('edges').tail(local,1))   

==>e[60944][60942-sentBy->60930]
==>e[60948][60946-sentBy->60933]
==>e[60952][60950-sentBy->60936]

gremlin> g.E(60944,60948,60952).valueMap()
==>[i:0,on:Fri May 14 21:58:01 CDT 2021]
==>[i:1,on:Fri May 14 22:00:12 CDT 2021]
==>[i:2,on:Fri May 14 22:00:44 CDT 2021]