Search code examples
azure-cosmosdbgremlinazure-cosmosdb-gremlinapi

Trouble simultaneously fetching filtered vertices and unfiltered vertices count


I'm trying to return a limited number of vertices matching a pattern, as well as the total (non-limited) count of vertices matching that pattern.

g.V()
  .hasLabel("PersonPublic")
  .has('partitionKey', "Q2r1NaG6KWdScX4RaeZs")
  .has('docId', "Q2r1NaG6KWdScX4RaeZs")
  .out("CONTACT_LIST")
  .out("SUBSCRIBER")
  .dedup()
  .order()
    .by("identifier")
    .by("docId")
  .fold()
  .project('people','total')
    .by(
      unfold()
      .has('docId', gt("23")),
      .limit(2)
      .project('type','id')
        .by(label())
        .by(values('docId'))
    )
    .by(unfold().count())

In plain English, I'm finding a person, finding all the contact lists of that person, finding all the subscribers to those contact lists, de-duplicating the subscribers, ordering the subscribers, pausing there to collect everything and then projecting the results in the form

{
  people: [{type: string, id: string}],
  total: number,
}
  • The "people" part of the projection is unfolded, filtered to only contain results with a "docId" greater than "23", limited to 2, and then projected again.

  • The "total" part of the projection is unfolded (no-limit) and counted.

My goal is to allow paging through a pattern while still retrieving the total number of vertices associated with the pattern.

Unfortunately, on cosmosdb this query is not working. Results are in the form

{
  people: {type: string, id: string},
  total: number,
}

And only the first person result is returned (rather than an array).

Any help would be greatly appreciated!


Solution

  • You need to fold() the projected value again, otherwise, it's always gonna be trimmed to the first one. Also, for the total you don't need to unfold(), that's just a waste of resources.

    g.V()
      .hasLabel("PersonPublic")
      .has('partitionKey', "Q2r1NaG6KWdScX4RaeZs")
      .has('docId', "Q2r1NaG6KWdScX4RaeZs")
      .out("CONTACT_LIST")
      .out("SUBSCRIBER")
      .dedup()
      .order()
        .by("identifier")
        .by("docId")
      .fold()
      .project('people','total')
        .by(
          unfold()
          .has('docId', gt("23"))
          .limit(2)
          .project('type','id')
            .by(label)
            .by('docId')
          .fold()
        )
        .by(count(local))