Gremlin Query Returns Different Structures Based on Page Size: Array vs Single Map

39 Views Asked by At

I'm working with Gremlin queries and encountering an unexpected behavior based on the page size specified. When I set the page size to more than one, the query returns an array of group maps under the groups key, as expected:

{
  "count": 2,
  "groups": [
    {
      "admin_team_ids": ["xxx"],
      "created_at": "2024-02-28T23:19:01Z",
      ...
    },
    {
      "admin_team_ids": ["xxx"],
      "created_at": "2024-02-28T23:19:01Z",
      ...
    }
  ]
}

However, when I change the page size to 1, the structure changes, and the groups key is followed by a single map instead of an array:

{
  "count": 2,
  "groups": {
    "admin_team_ids": ["xxx"],
    "created_at": "2024-02-28T23:16:37Z",
    ...
  }
}

I'm not sure which part of the Gremlin query is causing this behavior. Here's a snippet of the query(with pageSize=1; to change it to be more than 1, just update the "1" in the below snippet):

g.V('fcc6f904-d849-8293-f5c4-5c121e8e37df').
  outE('test-edge').inV().hasLabel('group').
  order().by('name', asc).
  valueMap().with(WithOptions.tokens).
  fold().as('groups', 'count').select('groups', 'count').by(range(local, 0, 1)).by(count(local))

(I am trying to get the direct outgoing vertices of a particular vertex, with pagination)

Is this a known behavior with Gremlin queries, or could it be related to how the results are being processed? How can I ensure that the groups key always returns an array, regardless of the page size?

This is not blocking us technically because we can do some special conditional checking when the page size is 1, but just wanted to know the best way to handle this scenario. Thank you in advance for any insights!

1

There are 1 best solutions below

4
Kelvin Lawrence On

Given that Gremlin will create a list result if there is more than one value, but return just the value if there is only one, probably the easiest way to handle this, and to get a consistent result format (assuming that is the goal), is to end the query with something like unfold().fold(). The unfold will do nothing if there is only one result but will remove the list if there is more than one result. The fold will then guarantee that all results come back in a list.

Here is a simple example of how this works

gremlin> g.V()
==>v[0]
==>v[1]

gremlin> g.V().fold().limit(local,1)
==>v[0]

gremlin> g.V().fold().limit(local,2)
==>[v[0],v[1]]

gremlin> g.V().fold().limit(local,1).unfold().fold()
==>[v[0]]

gremlin> g.V().fold().limit(local,2).unfold().fold()
==>[v[0],v[1]]

It's also fine to just special case the length of 1 case in the application logic instead.