skip to Main Content

I am building an api and I wanted to use the skip and limit methods in mongoose to handle pagination.
I would like to get the total document size along with the pagination data. Initially, I made two queries: one for the paginated data and the other for total document size. This is bad, right? I started searching if there is an inbuilt way to handle this on a single query. I came across aggregate method. Unfortunately, I have not been able to get it to work.

Here are my codes with two queries:

const page = req.query.page
 const {skip, searchlimit} = getPagination(params);
let transactionsData = []

const transactions = await TransactionModel.find({transactionOwnerId: user?._id}).sort({createdAt:-1})
  .skip(skip)
  .limit(searchlimit);

 totalDocumentSize = await TransactionModel.countDocuments({transactionOwnerId:   user?._id});

  transactionsData = transactions as transactionAttributes[];

console.log(transactionsData, totalDocumentSize)

Here, I tried the aggregate method:

 const me = await TransactionModel.aggregate([{
           $match: {transactionOwnerId: user?._id}
        }, 
         {
            $sort: {createdAt:-1}
         }
        
     ]);
console.log(me);

I believe that I am not applying the aggredate method properly. It is returning an empty array. How can I use it to apply the skip and limit methods and also get the total document size?

2

Answers


  1. You should try with $facet.

    Try this.I think it will work.

    const me = await TransactionModel.aggregate([
          { $match: { transactionOwnerId: user?._id } },
          {
            $facet: {
              transactions: [
                { $sort: { createdAt: -1 } },
                { $skip: skip },
                { $limit: limit },
              ],
              totalDocumentSize: [
                { $count: 'count' }
              ]
            }
          }
        ]);
    

    And then fetch each records using…

    const transactions = me[0].transactions;
    const totalDocumentSize = me[0].totalDocumentSize[0]?.count || 0;
    

    Note :- Make sure to run this query inside async() function.

    Login or Signup to reply.
  2. try this!

        const page = parseInt(req.query.page) || 1;
        const limit = 10;
    
        const transactions = await TransactionModel.aggregate([
          {
            $match: {
              $expr: { $eq: ["$transactionOwnerId", { $toObjectId: user?._id }] },
            },
          },
          {
            $facet: {
              data: [
                {
                  $skip: (page - 1) * limit,
                },
                {
                  $limit: limit,
                },
                {
                  $sort: { createdAt: -1 },
                },
              ],
              count: [
                {
                  $count: "count",
                },
              ],
            },
          },
        ]);
    
        console.log(transactions);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search