Mongoose查询GeoJSON餐厅按距离排序时返回结果为undefined的问题
核心问题定位
- 最直接的原因是Promise回调参数顺序使用错误
Mongoose的Model.find()返回的是标准Promise对象,then()回调只会接收1个参数,即查询成功后的结果集(此处为餐厅列表数组),查询错误会自动进入catch()分支,不会作为参数传入then()。
原代码中then的写法沿用了传统回调的(err, data)格式:
.then(function(err, restaurants){ console.log(restaurants); return res.json({success: true, restaurants: restaurants}); })
实际运行时,Promise会把查询到的餐厅数组赋值给第一个形参err,第二个形参restaurants因为没有对应传参,永远是undefined,最终接口返回的餐厅列表自然为空。
- 异常处理逻辑存在漏洞
当前catch中的if(err) throw err会把查询错误抛为未捕获的Promise异常,既不会给前端返回明确的错误信息,极端情况下还可能导致Node进程崩溃,需要直接返回错误响应。
修正后的代码
getRestaurantsNearYou: function(req, res){ if(req.headers.lng && req.headers.lat){ const lng = parseFloat(req.headers.lng); const lat = parseFloat(req.headers.lat); // 校验经纬度格式合法性 if(isNaN(lng) || isNaN(lat)) { return res.json({success: false, msg: res.__('invalidArgumentsErrorMsg')}) } Restaurant.find({ location: { $near: { $geometry: { type : "Point", coordinates : [lng, lat] }, $maxDistance: 5000 } } }).then((restaurants) => { // 仅接收查询结果作为参数 console.log(restaurants); return res.json({success: true, restaurants: restaurants}); }).catch(err => { console.error('附近餐厅查询失败:', err); return res.json({success: false, msg: res.__('serverErrorMsg')}); }); }else{ return res.json({success: false, msg: res.__('invalidArgumentsErrorMsg')}) } }
额外排查建议
- 确认2dsphere索引已正确构建:可在Mongo shell中执行
db.restaurants.getIndexes(),确认存在location字段的2dsphere索引,且索引构建完成(刚新增的索引可能处于后台构建状态,此时查询会返回空但不报错) - 确认经纬度顺序正确:GeoJSON格式的
coordinates要求为[经度, 纬度],传反会导致查询范围完全偏移到错误位置 - 可临时调大
$maxDistance(比如改为100000即100公里)测试,排除初始5000米的范围设置过小导致无匹配数据的问题
内容的提问来源于stack exchange,提问作者SeriousMonk
相关产品推荐
相关产品推荐

