公司的内部项目,不方便截图显示,请见谅
运行环境:
nodejs v14.16.0
MongoDB V4.2.3
问题
有一个需求,要通过接口查询客户的列表,数据里面带有形如gps:{X:118, y: 23}的坐标,微信小程序度使用此接口时,前端会将当前坐标、范围和一些查询条件传进来,接口要由近到远查询出相应的客户列表,并返回具体距离。PC端后台,则只有普通查询条件,接口返回相关数据。
早两天,产品说在小程序端加个距离不限的选项,其实就是距离设大点,设到3000km,全中国都覆盖了,接口早就预留,不用改。前端改了小程序,愉快地上线。
在开发环境、测试环境、预发布环境都没有问题,即PC端查询到该客户添加的5条数据,小程序在距离设为不限时,也可以查询5条出来。
完美,上生产呗。谁知上生产后,奇怪的事情就出现,在PC端查询到该客户添加的5条数据,小程序在距离设为不限时,就只可以查询2条出来。
说明:公司测试环境之后的环境部署都是k8s+Docker的模式。
代码
if (data.gps && Object.keys(data.gps).length > 0) {
aggobject.push({$geoNear: {near: data.gps, spherical: true, distanceField: "gps", distanceMultiplier: 6371, maxDistance: distance/6371}})
}
if (querywhere && Object.keys(querywhere).length > 0) {
aggobject.push({$match: querywhere})
}
排查
1、数据结构不对?将生产的数据搬到开发环境的库中,本地接口查询正常。
2、2d索引没建对?又重建了索引,问题依旧。
排除来排除去,估计是代码的写法问题,上到生产有些不兼容,问运维生产的mongodb是什么版本,又半天不回复。
解决方案
参照官方文档(https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/),换了一种写法。将查询语句写到geoNear里的query里面,放到生产环境,数据显示终于正常。
let geoNear = {near: data.gps, spherical: true, distanceField: "gps", distanceMultiplier: 6371, maxDistance: distance/6371}
if (querywhere && Object.keys(querywhere).length > 0) {
geoNear.query = querywhere
}
aggobject.push({$geoNear: geoNear})
算是解决了,但具体原因还在追查中,有时间再详细测试下。