Filtering and pagination with multiple terms

Consider the following GraphQL schema:

type Claim {
  startDate: Date!
  endDate: Date!
  status: ClaimStatus!
}

enum ClaimStatus {
  Active
  Complete
  Error
}

I am trying to create a query that can return all of the “active” claims, which are claims that have the Active status and claims where the current date falls within the startDate and endDate.

This is the query schema:

type Query {
  activeClaims: [Claim!]!
    @resolver(name: "get_active_claims", paginated: true)
}

But this is where I am sort of at a loss, all of the Paginate examples I’ve seen use a Match call along with an Index. If I had an array of docs, I think I could come up with the appropriate Filter combination to get a filtered array, but I haven’t really seen any examples that combine Filter with Paginate. Is it even possible?

Hi @shun,

I suppose you created startDate and endDate as Date(), in that case you can create 2 indexes:

CreateIndex({name:'refFromStartDate',source:Collection('dateSorting'),terms:[{field:['data','status']}],values:[{field:['data','startDate']},{field:['ref']}]})
CreateIndex({name:'refFromEndDate',source:Collection('dateSorting'),terms:[{field:['data','status']}],values:[{field:['data','endDate']},{field:['ref']}]})

and execute a query like the one below:

Intersection(
  Select(
    ['data'],
    Map(
      Paginate(Range(Match('refFromStartDate','Active'),[Date("2020-09-05")],[])),
      Lambda(['date','ref'],Var('ref'))
    )
  ),
  Select(
    ['data'],
    Map(
      Paginate(Range(Match('refFromEndDate','Active'),[],[Date("2020-09-20")])),
      Lambda(['date','ref'],Var('ref'))
    )
  )
)

The indexes will return all the Active documents and Range() filters out all documents depending on dates you specify.
At the end, you have to intersect re results from indexes.

Of course you can filter for any states and any dates.

Hope this helps.

Luigi

1 Like

@Luigi_Servini it does help to know that I need to setup 2 indexes to perform the Range checks but the part I am still unsure about is the multiple calls to Paginate.

What I think I need to do is paginate over the intersected result set.

For additional context, I am working within a custom GraphQL resolver UDF similar to the one posted here.

I agreed and then I didn’t

Map can only work over a Page. So you have to paginate first.

Also: I noticed that there was a missing Index function. It needs to be Match(Index(...), ...)

Okay, spit balling here, because I don’t have the data to test.

You can use Indexes with multiple values in a Range function. The docs use this example:

  Paginate(
    Range(
      Match(Index('people_by_age_first')),
      [80, 'Leslie'],
      [92, 'Marvin'],
    )
  )

Typically, with a one-value index you can provide null or an empty array and it will not filter on that end of the range. Is that doable when specifying more than one range value?

To modify the previous query, could we query all people over the age of 80, but all people with name before ‘Marvin’?

  Paginate(
    Range(
      Match(Index('people_by_age_first')),
      [80, null],
      [null, 'Marvin'],
    )
  )

such a thing would mean this could be answered with one Index and one Pagination step.

CreateIndex({
  name: 'StartDate_and_EndDate',
  source: Collection('dateSorting'),
  terms: [{ field: ['data', 'status'] }],
  values:[
    { field: ['data', 'startDate'] }, 
    { field: ['data', 'endDate'] }, 
    { field: ['ref'] }
  ] 
})
  Paginate(
    Range(
      Match(Index('StartDate_and_EndDate')),
      [Date("2020-09-05"), null],
      [null, Date("2020-09-20")],
    )
  )