Search code examples
mongodbmongoose

mongoose pagination returning the same document twice


I implement pagination by returning only two documents at a time. When paginating, I need to know if there are more documents to be fetched, or if the user is on the last page

Here is the existing code taken from This answer here

let pageCount = 2
let page = req.params.page

let result = await Chat.find()
    .skip(page * pageCount)
    .limit(pageCount + 1)

if (result.length === pageCount + 1) console.log("Has next page")
else console.log("On last page")

res.send(result)

This method works as expected as it correctly logs whether there is a next page or not. The issue I have is that when I increment the page, e.g from page 1 to page 2, I get returned duplicate documents. Documents which were also present on the previous page.

I tried changing the code for skip to skip(page * pageCount + 1), however this had no effect on fixing the issues.

Any ideas why this behavior is occurring, and any potential fixes? Thank you.


Solution

  • Let's say you've got pageCount = 2 and 10 documents. On page = 1, you'll skip page * pageCount = 2 documents _id = 1 and 2 and then get the next pageCount + 1 = 3, let's say _id = 3, 4, 5. (To get the documents on the actual first page, you need to do skip = (page - 1) * pageCount.)

    For page = 2, you'll skip 4 documents 1, 2, 3, 4 and get the next 3, so 5, 6, 7.

    So the 5 will repeat.

    And on page 3, it skips 6 documents 1 to 6 and returns 7, 8, 9, so the doc 7 will repeat.

    The purpose of the answer in the linked question to use limit + 1 is only to identify if you have more documents. Perhaps it should include that you should skip the last document returned IF you get exactly those many docs ie. total documents == pageCount.

    So on a certain page, if you get 3 docs, skip the 3rd doc (the last doc) in the results to finally return. It's only there to identify that you have more pages/docs. If you get only 2 docs then don't skip the 3rd doc (it doesn't exist), return the 2 docs and that's the last page.

    It would be something like this:

    if (result.length === pageCount + 1) {
      console.log("Has next page")
      res.send(result.slice(0, -1))
    } else {
      console.log("On last page")
      res.send(result)
    }