MongoDB分页加载评论的重复问题及排序兼容方案咨询
评论分页加载的问题与优化探讨
业务场景
网站加载用户评论时,初始仅展示部分内容,同时显示Load more按钮,点击后加载下一页评论并追加至评论列表末尾。
原分页实现(skip + limit)
最初采用MongoDB的skip和limit聚合操作实现分页,核心代码如下:
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();
原方案的核心问题
当有新评论发布时,原本属于第一页的部分评论会被挤到第二页,导致用户点击Load more后加载出重复评论,在UI中重复显示。
替代方案(基于时间戳的分页)
为解决重复问题,尝试不依赖页码,而是以最后加载的评论时间戳为起点查询后续内容,核心代码片段如下:
comments: [ { $match: { createdAt: { $gt: new Date(continueAfterTimestamp) } } }, { $limit: pageSize }, { $lookup: { from: 'resourcecomments', localField: '_id', foreignField: 'parentCommentId', as: 'replies', } } ],
替代方案的局限性
该方案存在两个无法忽视的问题:
- 极低概率下,若两条评论在同一毫秒发布,其中一条会被遗漏,无法加载到前端。
- 后续计划支持按点赞数排序评论时,时间戳无法作为查询定位的依据,该方案直接失效。
内容的提问来源于stack exchange,提问作者Florian Walther
相关产品推荐
相关产品推荐

