You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose分页返回重复文档问题排查与解决求助

分页重复问题的原因及修复方案

问题原因

  1. 页码起始逻辑不匹配:你的代码默认分页索引从0开始,但实际传入的page是从1开始的页码。当page=1时,skip(1*2)=2跳过前2条文档,取第3、4、5条;page=2时,skip(2*2)=4跳过前4条文档,取第5、6、7条,导致第5条文档重复出现在两页结果中。
  2. 未截断判断下一页的额外数据:你通过limit(pageCount+1)多取1条文档来判断是否有下一页,但直接将包含这条额外数据的结果返回给前端,既导致当前页结果条数超标,又让这条额外数据与下一页的第一条文档重复。

可行修复方案

方案1:修正分页索引+截断额外数据

调整skip的计算逻辑适配1起始页码,同时截断用于判断下一页的额外数据,只返回设定的每页条数:

const pageCount = 2;
// 转换页码为数字,处理无效页码
let page = parseInt(req.params.page, 10);
page = isNaN(page) || page < 1 ? 1 : page;

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

// 判断是否存在下一页
const hasNextPage = result.length === pageCount + 1;
// 截断额外数据,返回指定条数
const responseData = hasNextPage ? result.slice(0, pageCount) : result;

console.log(hasNextPage ? "Has next page" : "On last page");
// 建议把分页状态和数据一起返回,方便前端处理
res.send({
    data: responseData,
    hasNextPage: hasNextPage
});

方案2:使用游标分页(高性能无重复)

对于数据量较大的集合,skip会随着页码增大导致性能下降,且容易出现重复(比如分页期间有文档插入/删除)。用文档_id作为游标进行分页,彻底避免重复问题:

const { ObjectId } = require('mongodb'); // 需导入ObjectId
const pageCount = 2;
const lastId = req.query.lastId; // 前端传入上一页最后一条文档的_id

let query = {};
if (lastId) {
    // 只查询_id大于上一页最后一条的文档
    query._id = { $gt: ObjectId(lastId) };
}

let result = await Chat.find(query)
    .limit(pageCount + 1);

const hasNextPage = result.length === pageCount + 1;
const responseData = hasNextPage ? result.slice(0, pageCount) : result;
// 返回当前页最后一条的_id,供下一页查询使用
const nextLastId = hasNextPage ? responseData[responseData.length - 1]._id : null;

console.log(hasNextPage ? "Has next page" : "On last page");
res.send({
    data: responseData,
    hasNextPage: hasNextPage,
    nextLastId: nextLastId
});

方案3:确保页码为有效数字

先将req.params.page转换为数字,避免字符串类型导致的运算异常:

let page = parseInt(req.params.page, 10);
// 处理非数字、小于1的无效页码
if (isNaN(page) || page < 1) {
    page = 1;
}

内容的提问来源于stack exchange,提问作者Eesa Munir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:05:30