Mongodb geonear和聚合非常慢

时间:2016-11-16 10:01:13

标签: mongodb mongodb-query geospatial mongodb-aggregation

我目前的mongo版本是2.4.9,而且集合大约有280万行。在查询中使用$ geonear时,我的查询需要超长时间才能完成。

我的收藏示例

"loc" : {
    "type" : "Point",
    "coordinates" : [ 
        100.46589473, 
        5.35149077
    ]
},
"email" : "abc@123.com"

loc index

{
    "v" : 1,
    "key" : {
        "loc" : "2dsphere"
    },
    "ns" : "test.collect",
    "name" : "loc_2dsphere",
    "background" : true
}

测试此查询将需要大约10到15分钟才能完成

db.getCollection('collect').aggregate(
  [
  { '$match':
         {'loc':
             {'$geoNear':
                 {'$geometry':
                     {'type':'Point','coordinates':[101.6862,3.0829],'$maxDistance':10000}
                  }
             }
         } 
  },
  {'$group':{'_id':'email', 'email':{'$last':'$email'},'loc':{'$last':'$loc'} }}
  ])

以下是解释结果

{
"serverPipeline" : [ 
    {
        "query" : {
            "loc" : {
                "$geoNear" : {
                    "$geometry" : {
                        "type" : "Point",
                        "coordinates" : [ 
                            101.6862, 
                            3.0829
                        ],
                        "$maxDistance" : 10000
                    }
                }
            }
        },
        "projection" : {
            "email" : 1,
            "loc" : 1,
            "_id" : 0
        },
        "cursor" : {
            "cursor" : "S2NearCursor",
            "isMultiKey" : true,
            "n" : 111953,
            "nscannedObjects" : 111953,
            "nscanned" : 96677867,
            "nscannedObjectsAllPlans" : 111953,
            "nscannedAllPlans" : 96677867,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nYields" : 183,
            "nChunkSkips" : 0,
            "millis" : 895678,
            "indexBounds" : {},
            "nscanned" : NumberLong(96677867),
            "matchTested" : NumberLong(3472481),
            "geoMatchTested" : NumberLong(3472481),
            "numShells" : NumberLong(53),
            "keyGeoSkip" : NumberLong(93205386),
            "returnSkip" : NumberLong(20148837),
            "btreeDups" : NumberLong(0),
            "inAnnulusTested" : NumberLong(3472481),
            "allPlans" : [ 
                {
                    "cursor" : "S2NearCursor",
                    "n" : 111953,
                    "nscannedObjects" : 111953,
                    "nscanned" : 96677867,
                    "indexBounds" : {}
                }
            ],
            "server" : "xxx:xxx"
        }
    }, 
    {
        "$group" : {
            "_id" : {
                "$const" : "email"
            },
            "email" : {
                "$last" : "$email"
            },
            "loc" : {
                "$last" : "$loc"
            }
        }
    }
],
"ok" : 1
}

我的查询是否不合适,我还能做些什么来提高速度?

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

添加到venkat的答案(直接在汇总管道中使用$geoNear,而不是在$match下使用它):

此外,MongoDB 2.4于2013年3月发布,不再受支持。如果可能,我建议您升级到最新版本(目前为3.2.10)。新版本中有许多错误修正和性能改进。

答案 2 :(得分:0)

使用聚合框架的$geoNear 比下面(查找查询)更快地工作

"$near": {
        "$geometry": {
            "type": "Point",
            "coordinates": [lng,lat],
        },
},

在某个地方,我的 mongodb 也被后者转到“没有可用的套接字”,但前者效果很好(<20 毫秒)[也从 golang + mgo 驱动程序测试]