Paginated query on collection for GraphQL: Best Practices

Hello,
I want to know about the best practices for paginated query on collection.
I am using skip based pagination in application and Graphql as a API layer.

Let’s say there is a User collection with more than 100K Documents.

So, in Graphql query resolver, I am doing two parallel calls,

  1. Fetching user document from User collection (pagesize: 10 and pagenumber: 1)
  2. Fetching total user document count from User collection (db.collection.countDocuments())

These two call will happen for every page (eg. for page: 2, 3, 4, …)
So, My question is that, is this the proper way to handle the paginated query or these two calls (data fetch and count fetch) will add an overhead to the mongodb pod/container?

Note: Here, we want skip based pagination, no cursor based pagination.

Thanks in advance

Hi @Nisarg_Bhatt2 ,

To implement pagination you can use a single aggregation pipeline instead of hitting two calls (Data & Count).

Here are the best practices for implementing pagination as follows:

// Method 1:  using $setWindowFields

[
// {write your logic here},
  {
    $setWindowFields: {
      sortBy: {
        sortField: -1  // to ensure the data is in the correct order
      },
      output: {
        docCount: {
          $count: {}
        }
      }
    }
  },
  {
    $skip: 0  
  },
  {
    $limit: 10
  }
]
it will add the total count in each document in the query output.



// Method 2 : using  $facet

[
 // {write your logic here},
  {
    $facet: {
      documents: [
        {
          $sort: {
            sortField: -1  // to ensure the data is in the correct order
          }
        },
        {
          $skip: 0
        },
        {
          $limit: 10
        }
      ],
      docCount: [
        {
          $count: "count"
        }
      ]
    }
  },
  {
    $set:
      {
        docCount: {
          $first: "$docCount.count"
        }
      }
  }
]

It will give a count and data in a single document. 

With the above aggregations can fulfill your requirement and hit only one time to the database instead of two calls.

I hope this helps!