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
相关产品推荐
相关产品推荐

