Mongoose 6与NodeJS中排序功能失效及正确用法咨询
解决Mongoose 6中数据排序的问题
错误原因分析
你当前的代码逻辑存在两处核心问题:
- 把排序参数
sort直接赋值给过滤条件对象queryString,导致Tour.find()接收的是字符串(比如price)而非合法的过滤对象,触发Parameter "filter" to find() must be an object错误。 - 尝试调用普通JS对象的
sort()方法,但sort()是Mongoose Query实例的专属方法,普通对象没有该方法,因此出现queryString.sort is not a function错误。
正确实现思路
Mongoose查询需要分离过滤条件与排序、分页等查询选项,通过链式调用Query实例的方法来实现排序功能,具体步骤如下:
- 先从请求参数中移除
sort这类非过滤字段,单独处理过滤条件 - 构建基础查询实例
- 若存在
sort参数,链式调用sort()方法配置排序规则 - 执行最终查询
修正后的控制器代码
exports.getAllTours = async (req, res) => { try { // 1. 复制请求参数,移除sort等非过滤字段 const queryObj = { ...req.query }; const excludedFields = ['sort']; excludedFields.forEach(el => delete queryObj[el]); // 2. 处理gte/gt/lte/lt等比较操作符 let queryString = JSON.stringify(queryObj); queryString = queryString.replace( /\b(gte|gt|lte|lt)\b/g, (match) => `$${match}` ); const filterQuery = JSON.parse(queryString); // 3. 构建基础查询实例 let query = Tour.find(filterQuery); // 4. 配置排序规则 if (req.query.sort) { // 支持多字段排序,比如?sort=-price,rating(价格降序、评分升序) const sortBy = req.query.sort.split(',').join(' '); query = query.sort(sortBy); } else { // 设置默认排序规则,比如按创建时间降序 query = query.sort('-createdAt'); } // 5. 执行查询 const tours = await query; res .status(200) .json({ status: 'ok', results: tours.length, data: { tours } }); } catch (err) { console.log(err); res.status(404).json({ status: 'failure', results: err.message }); } };
关键细节说明
sort()方法的参数规则:传入'price'表示价格升序,'-price'表示价格降序;多字段排序用空格分隔,比如'-price rating'。- Mongoose 6与5的
sort()用法基本一致,你的问题核心是逻辑错误,而非版本差异。 - 必须先通过
Tour.find(filterQuery)创建Query实例,再链式调用sort(),不能直接在普通JS对象上调用该方法。
内容的提问来源于stack exchange,提问作者Eudeamonism
相关产品推荐
相关产品推荐

