Home > Back-end >  Is there a way to paginate through populated documents using mongoose-paginate-v2?
Is there a way to paginate through populated documents using mongoose-paginate-v2?

Time:06-10

I've got User and Post models. User.favPosts is an array of refs to the Post model. I'm calling paginate like this:

options = { populate: {path: 'favPosts'} };
const result = await User.paginate({}, options)

And the result is a user document with populated posts:

{
  "docs": [
    {
      "_id": "6299ffa5c2ca4cdeebd1f513",
      "name": "user",
      "email": "[email protected]",
      "favPosts": [
        {
          "_id": "629b299897f46f31761ad7a7",
          "title": "Available Test 5",
          "description": "Lorem ipsum dolor sit"
        },
        {
          "_id": "629b1edf108e765744d2560d",
          "title": "Available Test 4",
          "description": "Lorem ipsum dolor sit"
        },
        {
          "_id": "629b1c0027bf0eb197c057dd",
          "title": "Available Test 4",
          "description": "Lorem ipsum dolor sit"
        }
      ]
    }
  ],
  "totalDocs": 1,
  "offset": 0,
  "limit": 10,
  "totalPages": 1,
  "page": 1,
  "pagingCounter": 1,
  "hasPrevPage": false,
  "hasNextPage": false,
  "prevPage": null,
  "nextPage": null
}

So I'm getting the pagination of users. But I want to get pagination of populated documents (posts), so I could get the amount of these, page counting, etc. So I want the result to look like this:

{
  "docs": [
    {
      "_id": "629b299897f46f31761ad7a7",
      "title": "Available Test 5",
      "description": "Lorem ipsum dolor sit"
    },
    {
      "_id": "629b1edf108e765744d2560d",
      "title": "Available Test 4",
      "description": "Lorem ipsum dolor sit"
    },
    {
      "_id": "629b1c0027bf0eb197c057dd",
      "title": "Available Test 4",
      "description": "Lorem ipsum dolor sit"
    }
  ],
  "totalDocs": 3,
  "offset": 0,
  "limit": 10,
  "totalPages": 1,
  "page": 1,
  "pagingCounter": 1,
  "hasPrevPage": false,
  "hasNextPage": false,
  "prevPage": null,
  "nextPage": null
}

Can somebody tell me, is it possible to do such a thing via the mongoose-paginate-v2?

CodePudding user response:

Here's how I solved it. I used the mongoose-aggregate-paginate-v2 module instead of mongoose-paginate-v2:

const aggregate = User.aggregate([ // without "await", so it will be a Promise
    { $match: { userId } }, // filter for users collection
    {
// populating posts:
        $lookup: {
            from: 'posts',
            localField: 'favPosts',
            foreignField: '_id',
            as: 'documents',
            pipeline, // here's filter for posts
        },
    },
// unwind   replaceRoot to get an array of posts to the root, so this would be the posts array instead of the users array
    {
        $unwind: '$documents',
    },
    {
        $replaceRoot: { newRoot: '$documents' },
    },
]);

And then feeding this Promise to the paginator:

const options = { page: 2, limit: 10 };
const result = await User.aggregatePaginate(aggregate, options);
  • Related