Gremlin: limit by vertex label

Viewed 145

Hello dear gremlin jedi,

I have a bunch of nodes with different labels in my graph:

  g.addV('book')
   .addV('book')
   .addV('book')
   .addV('movie')
   .addV('movie')
   .addV('movie')
   .addV('album')
   .addV('album')
   .addV('album').iterate()

There also may be vertices with other labels.

and a hash map describing what labels and how many vertices of each label I want to get:

LIMITS = {
  "book": 2,
  "movie": 2,
  "album": 2,
}

I'd like to write a query that returns a list of vertices consisting of vertices with specified labels whete amount of vertices with each label is limited in according to the LIMITS hash map. In this case there should be 2 books, 2 movies and 2 albums in the result.

The limits and requested labels are calculated independently for every query so they cannot be hardcoded.

As far as I can see the limit step does not support passing traversals as an argument.

What trick can I use to write such query? The only option I see is to build the query using capabilities of the client side programming language (Ruby with grumlin as a gremlin client in my case):

  nodes = LIMITS.map do |label, limit|
    __.hasLabel(label).limit(limit)
  end

   g.V().union(*nodes).toList

But I believe there is a better solution.

Thank you!

1 Answers

The most direct way would be to use group() I think:

gremlin> g.V().group().by(label)
==>[software:[v[3],v[5]],person:[v[1],v[2],v[4],v[6]]]
gremlin> g.V().group().by(label).by(unfold().limit(2).fold())
==>[software:[v[3],v[5]],person:[v[1],v[2]]]

You can filter the vertices going to group() with hasLabel() if you need those sorts of restrictions. Depending upon how you use this, the traversal could be expensive in the sense that you have to traverse a fair bit of data to filter away all but two (in this case) vertices. If that is a concern, your approach to dynamically construct the traversal and the piecing it together with union() doesn't seem so bad. While I could probably think up a way to write that in just Gremlin, it probably wouldn't not be as readable as your approach.

Related