Search code examples
gremlintinkerpop

Tinkerpop Gremlin group by key and get latest


I am creating 2 users(uid=1 & uid=2) with 2 versions each.

g.addV('user1').property('uid',1).property('version',1)
 .addV('user1').property('uid',1).property('version',2)
 .addV('user1').property('uid',2).property('version',1)
 .addV('user1').property('uid',2).property('version',2)

I want to get the latest version from each uid, I am using the uid as a groupBy key and getting the latest as shown

g.V().hasLabel('user1')
.group().by('uid').by(fold().order(Scope.local).by('version', Order.desc).unfold().limit(1)) //GraphTraversal<Vertex,Map<Object, Object>>
.flatmap(t -> t.get().values().iterator()) // convert to GraphTraversal<Vertex, Vertex>
//traverse out and get the path
.out('friend').path().by(elementMap())
  1. Is the best approach for this requirement?
  2. What would be the gremlin preferred way to convert the Map to a Vertex inside the flatmap rather than using the lambda? Suppose I want to add further steps after this.

Appreciate any help!


Solution

  • The group step has two modes. Without a label it acts as a barrier but with a label it acts as a side effect. You can have results flow through a group using your data as follows.

    gremlin> g.V().group('x').by('uid').by(values('version').max())
    ==>v[42306]
    ==>v[42309]
    ==>v[42312]
    ==>v[42315]
    ==>v[42318]  
    
    gremlin> g.V().group('x').by('uid').by(values('version').max()).cap('x')
    ==>[1:2,2:2]  
    

    You can add more traversal steps of course before you decide what you want to do with the group. Such as:

    g.V().group('x').by('uid').by(values('version').max())out()...