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

类似于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 쉘에서 explain을 사용하여 SQL을 파싱하고, 파싱을 기반으로 인덱스를 구축하는 동시에 가장 왼쪽 접두사 일치의 원칙을 고려해야 합니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿