类似于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时间。
应该如何优化?
やっとインデックスを作成しました
cityid: 1, shopid: 1, "location" : "2dsphere"
その後、世界は再び平和になりました。
この方法でインデックスを構築すれば確かに問題は解決できますが、ここで見落とされがちな点を強調したいと思います: 最初に強力なフィルタリング条件を設定します
その方法がわからないからですデータは分散されているため、インデックスがこのベスト プラクティスを満たしているかどうかを判断することはできません。しかし、
shopid
が異なる都市で繰り返されない限り (通常はそのように設計されていないと思われます)、cityid
はまったく効果がなく、インデックスに配置する必要がなく、筆圧が高まるだけのようです。mongo シェルで Explain を使用して SQL を解析し、同時に、左端の接頭辞の一致の原則を考慮する必要があります。