MongoDB多$nearSphere查询报错Too many geoNear expressions,求替代方案
MongoDB「Too many geoNear expressions」错误的替代解决方案
执行包含两个$nearSphere条件的$and查询时,会触发「Too many geoNear expressions」错误,原查询语句如下:
{$and:[{ 'polylineLocs': { '$nearSphere': { '$geometry': { 'type': 'Point', 'coordinates': [78.02478824054135, 30.29090638871556 ] }, '$maxDistance': 250, '$minDistance': 0 } } }, {'location': { '$nearSphere': { '$geometry': { 'type': 'Point', 'coordinates': [ 78.0009260423163, 30.266704531034748 ] }, '$maxDistance': 150, '$minDistance': 0 } } }]}
可行替代方案:
- 用
$geoWithin替换其中一个$nearSphere
MongoDB限制单个查询只能包含一个$near/$nearSphere类型的地理条件,因此可以把其中一个范围判断换成$geoWithin+$centerSphere组合,它支持在同一查询中使用多个地理条件。注意$geoWithin只做范围匹配,不会返回按距离排序的结果,如果业务不需要排序,这个方案最直接。
修改后的查询示例:
{$and:[{ 'polylineLocs': { '$nearSphere': { '$geometry': { 'type': 'Point', 'coordinates': [78.02478824054135, 30.29090638871556] }, '$maxDistance': 250, '$minDistance': 0 } }, {'location': { '$geoWithin': { '$centerSphere': [ [78.0009260423163, 30.266704531034748], 150 / 6378137 // 转换为弧度,地球半径约6378137米 ] } } }]}
先单条件查询,再在应用层过滤
先执行其中一个$nearSphere查询拿到初步结果,然后在应用代码里计算剩余字段与目标点的距离,筛选符合第二个条件的文档。这个方案适合结果集不大的场景,避免数据库层面的限制,但要注意如果初始结果集过大,会增加应用层的计算压力。使用聚合管道处理
利用聚合管道的$geoNear阶段先处理第一个地理条件($geoNear必须是聚合的第一个阶段),再通过$match阶段结合$geoWithin处理第二个地理条件。需要确保两个地理字段都创建了对应的2dsphere索引。
聚合示例:
db.collection.aggregate([ { '$geoNear': { 'near': { 'type': 'Point', 'coordinates': [78.02478824054135, 30.29090638871556] }, 'distanceField': 'polylineDistance', 'maxDistance': 250, 'minDistance': 0, 'spherical': true, 'key': 'polylineLocs' } }, { '$match': { 'location': { '$geoWithin': { '$centerSphere': [ [78.0009260423163, 30.266704531034748], 150 / 6378137 ] } } } } ])
内容的提问来源于stack exchange,提问作者Mathomania
相关产品推荐
相关产品推荐

