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

Mongoose分页查询报错query.skip is not a function如何解决

报错根因
  • 你在Order.find()前加了await,此时拿到的userOrders已经是MongoDB返回查询结果后生成的普通JavaScript数组,不再是Mongoose的可链式调用Query实例。普通数组只有JS原生的数组方法,不存在Mongoose提供的.skip()、.limit()数据库查询方法,所以会抛出xxx.skip is not a function错误。
  • Mongoose的.sort()方法是把排序规则传递给MongoDB在数据库层面执行,不接受JavaScript比较函数作为入参,你传入数组排序用的比较函数时,就会触发Invalid sort() argument. Must be a string, object, or array.报错。
正确修复写法

所有链式查询逻辑全部拼接完成后,再调用await执行查询拿到最终结果,排序规则使用Mongoose支持的格式,按创建时间倒序(最新到最旧)用{ createdAt: -1 }即可:

orderRouter.get(
    '/mine',
    isAuth,
    expressAsyncHandler(async (req, res) => {
        const page = parseInt(req.query.page) || 1;
        const perPage = parseInt(req.query.limit) || 20;
        const skip = (page - 1) * perPage;
        // 链式拼接查询、排序、分页逻辑,最后统一await执行
        const orders = await Order.find({ user: req.user._id })
            .sort({ createdAt: -1 }) // -1代表倒序,即最新数据在前
            .skip(skip)
            .limit(perPage);
        
        res.status(200).send(orders);
    }),
);
注意事项
  • 所有Mongoose查询链式方法(find/sort/skip/limit/select等)都必须写在await之前,一旦提前await,拿到的就是最终的普通数组结果,无法再调用数据库查询相关的链式方法。
  • 不要先查询全量数据再在Node.js内存里做排序、分页,数据量上涨后会严重拖慢接口性能,把排序、分页逻辑全部交给MongoDB在数据库层面执行,效率最高。
  • Mongoose的.sort()支持三种合法入参格式:
    • 对象格式:{ createdAt: -1 }为倒序,{ createdAt: 1 }为正序
    • 字符串格式:'-createdAt'为倒序,'createdAt'为正序
    • 数组格式:[['createdAt', -1]]

内容的提问来源于stack exchange,提问作者pelotador.1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:09:18