mongoDB不会合并1d和2d索引,地理查询会扫描所有文档,而不管应用哪些过滤器来限制记录数量

时间:2014-12-19 15:43:16

标签: mongodb indexing 2d

以下是其中一个查询的解释输出:

{
    "cursor" : "GeoSearchCursor",
    "isMultiKey" : false,
    "n" : 0,
    "nscannedObjects" : **199564**,
    "nscanned" : 199564,
    "nscannedObjectsAllPlans" : **199564**,
    "nscannedAllPlans" : **199564**,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 1234,
    "indexBounds" : {

    },
    "server" : "MongoDB",
    "filterSet" : false
}

此查询扫描所有 199564 记录,其中在查询的过滤器中应用约束,该记录应仅为几百条记录。

非常感谢指针

添加应用的查询和索引:

查询

  

{          “isfeatured”:1,          “状态”:1,          “isfesturedseq”:1,          “loc_long_lat”:{              “$ near”:[76.966438,11.114906]          },          “city_id”:“40”,          “showTime.0”:{“$ exists”:true}}

索引

{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "name" : "_id_",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "loc_long_lat" : "2d"
    },
    "name" : "loc_long_lat_2d",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "georand" : "2d"
    },
    "name" : "georand_2d",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "city_id" : 1
    },
    "name" : "city_id_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "endDatetime" : 1
    },
    "name" : "endDatetime_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "movieid" : 1
    },
    "name" : "movieid_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "theaterid" : 1
    },
    "name" : "theaterid_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "status" : 1
    },
    "name" : "status_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "isfeatured" : 1
    },
    "name" : "isfeatured_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "isfesturedseq" : 1
    },
    "name" : "isfesturedseq_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "is_popular" : 1
    },
    "name" : "is_popular_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "loc_name" : 1
    },
    "name" : "loc_name_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "est_city_id" : 1
    },
    "name" : "est_city_id_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "isfeatured" : 1,
        "status" : 1,
        "city_id" : 1
    },
    "name" : "isfeatured_1_status_1_city_id_1",
    "ns" : "test_live.movies_theater_map",
    "background" : true
},
{
    "v" : 1,
    "key" : {
        "movieid" : 1,
        "endDatetime" : 1,
        "city_id" : 1,
        "status" : 1
    },
    "name" : "movieid_1_endDatetime_1_city_id_1_status_1",
    "ns" : "test_live.movies_theater_map",
    "background" : 2
},
{
    "v" : 1,
    "key" : {
        "movieid" : 1,
        "endDatetime" : 1,
        "city_id" : 1,
        "status" : 1,
        "georand" : 1
    },
    "name" : "movieid_1_endDatetime_1_city_id_1_status_1_georand_1",
    "ns" : "test_live.movies_theater_map",
    "background" : 2
},
{
    "v" : 1,
    "key" : {
        "rand" : 1
    },
    "name" : "rand_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "isfeatured" : 1,
        "city_id" : 1,
        "status" : 1
    },
    "name" : "isfeatured_1_city_id_1_status_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "movieid" : 1,
        "city_id" : 1
    },
    "name" : "movieid_1_city_id_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "loc_long_lat" : 1,
        "is_popular" : 1,
        "movieid" : 1,
        "status" : 1
    },
    "name" : "loc_long_lat_1_is_popular_1_movieid_1_status_1",
    "ns" : "test_live.movies_theater_map"
},
{
    "v" : 1,
    "key" : {
        "status" : 1,
        "city_id" : 1,
        "theaterid" : 1,
        "endDatetime" : 1
    },
    "name" : "status_1_city_id_1_theaterid_1_endDatetime_1",
    "ns" : "test_live.movies_theater_map",
    "background" : true
}

1 个答案:

答案 0 :(得分:0)

$near运算符使用2d或2dsphere索引按从最近到最远的顺序返回文档。对于2d索引,最多返回100个文档。您的查询扫描了每个文档,因为没有匹配的文档,并且必须扫描从最近到最远的每个文档以检查它是否符合所有条件。

我建议以下内容来改进查询:

  1. 使用$maxDistance选项(以弧度指定旧版坐标)来限制扫描的最大文档数。
  2. 使用2dsphere索引,理想情况下使用GeoJSON点而不是传统坐标。您可以使用具有2dsphere索引的地理索引具有前缀键的复合索引,因此您可以部分地根据所有其他条件索引查询以减少需要扫描的文档数。您使用的是哪个版本的MongoDB?旧版本可能没有提供所有这些功能。
  3. 使用limit限制扫描的最大文档数。但是,当查询的结果少于limit的值时,您仍会扫描每个文档。