python - mongodb 按照距离排序查询很慢
PHP中文网
PHP中文网 2017-04-17 18:01:47
0
3
600

类似于lbs的服务,需要按照用户位置的距离排序。

集合的结构:

{
    "_id" : ObjectId("574bbae4d009b5364abaebe5"),
    "cityid" : 406,
    "location" : {
        "type" : "Point",
        "coordinates" : [
            118.602355,
            24.89083
        ]
    },
    "shopid" : "a"
}

差不多5万条数据。

索引:

[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "pingan-test.shop_actinfo_collection_0530"
    },
    {
        "v" : 1,
        "key" : {
            "location" : "2dsphere"
        },
        "name" : "location_2dsphere",
        "ns" : "pingan-test.shop_actinfo_collection_0530",
        "2dsphereIndexVersion" : 3
    },
    {
        "v" : 1,
        "key" : {
            "shopid" : 1,
            "cityid" : 1
        },
        "name" : "shopid_1_cityid_1",
        "ns" : "pingan-test.shop_actinfo_collection_0530"
    }
]

查询的条件是:

{'cityid': 2, 'location': {'$near': {'$geometry': {'type': 'Point', 'coordinates': [122.0, 31.0]}}}, 'shopid': {'$in': ['a','b']}}

当使用pymongo查询的时候,迭代会消耗大概300ms的时间,这个难以接受。

results = collection.find(body, {'shopid': 1, '_id':0},).batch_size(20).limit(20)
shops = list(results)

第一步获取一个游标,几乎没有消耗时间;
第二部对这个有标进行迭代消耗300~400ms时间。

应该如何优化?

PHP中文网
PHP中文网

认证0级讲师

全部回覆(3)
黄舟

最後,我只是創建索引 cityid: 1, shopid: 1, "location" : "2dsphere"
之後,世界再次和平了。

小葫芦

這樣建索引固然能夠解決問題,這裡要強調經常被大家忽略的一點:過濾性強的條件放前面
因為不知道你的數據如何分佈,所以沒法判斷你的索引是不是滿足這個最佳實踐。但看起來,除非shopid在不同城市有重复(我怀疑通常不会这么设计),否则cityid根本沒有作用,不用放在索引裡,徒增寫壓力。

黄舟

在mongo shell中使用explain對sql進行解析,在解析基礎上建立索引,同時需要考慮最左前綴匹配的原則;

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板