5

I'm currently using TinkerPop java APIs for graph traversal. Currently I had to create a duplicate copy of the same traversal to compute the count.

Long allUsersCount = gt.V().hasLabel("user").has("name", "John").count().next();
List<Vertex> users = gt.V().hasLabel("user").has("name", "John").toList();

When I tried to reuse the traversal returned by gt.V().hasLabel("user").has("name", "John").count() to get the list, it caused the error

java.lang.IllegalStateException: The traversal strategies are complete and the traversal can no longer be modulated

I just want to know if there is any way to avoid this repetition as the traversal is same for both cases gt.V().hasLabel("user").has("name", "John") just the terminating operations are different.

Is there any way to store the count in-between(inside a java variable) and continue the traversal to get the list of users.

Vivek
  • 11,938
  • 19
  • 92
  • 127

2 Answers2

7

The count() step is a "reducing barrier step" which is why you see the behavior you do. There are many ways to work around this. Here is one example that uses the air-routes data set.

gremlin> g.V().has('city','London').
               fold().
               project('cities','count').
                 by().
                 by(count(local))

==>[cities:[v[49],v[50],v[88],v[94],v[206],v[649]],count:6]    
Kelvin Lawrence
  • 14,674
  • 2
  • 16
  • 38
  • 1
    I'm still learning the ins and outs of Gremlin, and this was very helpful! My requirement was to return a count with just the first instance from the set of objects alongside the total count, so I used `fold()` like you did above, and combined that with `unfold().limit(1)` in the projection. ```...fold().project('city','count').by(unfold().limit(1)).by(count(local))``` – Gyromite Jan 12 '22 at 00:53
5

You can achieve this by projecting your results and using a count() step with a local scope.

g.V().fold().project('cnt', 'edges').by(count(local)).by()

returns this:

==>[cnt:6,edges:[v[1],v[2],v[3],v[4],v[5],v[6]]]

Local scope (i.e. count(local)) will perform the desired operation on each list inside the current object. In this case we are finding all vertices, collecting them into a list. Once we are in the project() we are then counting the local scope (i.e. the number of items in the list) and returning that count along with the original list.

bechbd
  • 6,206
  • 3
  • 28
  • 47