title: Resume pagination after specific document
body: <p>I'm loading user comments on my website. Initially, I only load a subset of comments and show a <code>Load more</code> button which loads the next page and <strong>appends it to the end of the comments list</strong>.</p>
  <p><a href="https://i.stack.imgur.com/KjwnR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/KjwnR.png" alt="enter image description here" /></a></p>
  <p>Loading another page works by using the usual <code>skip</code> and <code>limit</code> aggregation steps in MongoDB:</p>
  <pre><code>const aggregationResult = await ResourceCommentModel.aggregate()
      .match({
          resourceId: new mongoose.Types.ObjectId(req.params.resourceId),
          parentCommentId: undefined
      })
      .sort({ 'createdAt': -1 })
      .facet({
          comments: [
              { $skip: (page - 1) * pageSize },
              { $limit: pageSize },
              {
                  $lookup: {
                      from: 'resourcecomments',
                      localField: '_id',
                      foreignField: 'parentCommentId',
                      as: 'replies',
                  }
              }
          ],
          totalCount: [{ $group: { _id: null, count: { $sum: 1 } } }]
      })
      .exec();
  </code></pre>
  <p><strong>Problem: If new comments have been posted in the meantime, comments from page one have been pushed to page 2, and we are loading duplicate comments (and showing them in the UI).</strong></p>
  <p><a href="https://i.stack.imgur.com/FUpgQ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FUpgQ.png" alt="enter image description here" /></a></p>
  <p>One option would be to not rely on the <code>page</code> number, but instead start after the last loaded timestamp:</p>
  <pre><code>comments: [
      { $match: { createdAt: { $gt: new Date(continueAfterTimestamp) } } },
      { $limit: pageSize },
      {
          $lookup: {
              from: 'resourcecomments',
              localField: '_id',
              foreignField: 'parentCommentId',
              as: 'replies',
          }
      }
  ],
  </code></pre>
  <p>However, there are <strong>2 problems</strong> with this approach:</p>
  <ol>
  <li><p>Although unlikely, if two comments were posted at the exact same millisecond, one of them will not be loaded.</p>
  </li>
  <li><p>The bigger problem: I'm planning to later allow sorting comments by upvotes, and then I don't have a way to start after the last loaded document anymore.</p>
  </li>
  </ol>