찾다

 >  Q&A  >  본문

python - mongodb 按照距离排序查询很慢

类似于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中文网2889일 전609

모든 응답(3)나는 대답할 것이다

  • 黄舟

    黄舟2017-04-17 18:03:47

    드디어 방금 인덱스를 만들었습니다 cityid: 1, shopid: 1, "location" : "2dsphere"
    그 후 세상은 다시 평화로워졌습니다.

    회신하다
    0
  • 高洛峰

    高洛峰2017-04-17 18:03:47

    이런 방식으로 인덱스를 구축하면 확실히 문제가 해결될 수 있지만 여기서는 종종 간과되는 점을 강조하고 싶습니다. 강력한 필터링 조건을 먼저 설정
    방법을 모르기 때문입니다. 귀하의 데이터가 분산되어 있으므로 귀하의 인덱스가 이 모범 사례를 충족하는지 판단할 수 없습니다. 그러나 shopid가 다른 도시에서 반복되지 않는 한(보통 이런 식으로 설계되지 않는 것으로 생각됩니다) cityid은 전혀 효과가 없으며 색인에 포함될 필요가 없으며 이는 쓰기 압력만 증가시킬 뿐입니다.

    회신하다
    0
  • 黄舟

    黄舟2017-04-17 18:03:47

    mongo 쉘에서 explain을 사용하여 SQL을 파싱하고, 파싱을 기반으로 인덱스를 구축하는 동시에 가장 왼쪽 접두사 일치의 원칙을 고려해야 합니다.

    회신하다
    0
  • 취소회신하다