为什么它访问的文档数量超过它应该在Mongodb中访问的文档数量

时间:2018-06-11 10:53:53

标签: mongodb mongodb-query query-performance mongodb-indexes

以下是包含5个文档的示例数据。我们称这个集合为测试

{ 
"_id" : "asdfasdsf2123412324poio12323n21344d",
"info" : [
    {
        "dates" : [
            {
                "date" : ISODate("2017-03-01T00:00:00.000+0000")
            }
        ], 
        "cm" : "not_set", 
        "ci" : "unknown", 
        "co" : "Albania", 
        "dev" : "mobile", 
        "lan" : "en", 
        "st" : "unknown", 
    }, 
    {
        "dates" : [
            {
                "date" : ISODate("2017-02-27T11:00:00.000+0000")
            }
        ], 
        "cm" : "not_set", 
        "ci" : "unknown", 
        "co" : "Albania", 
        "dev" : "mobile", 
        "lan" : "en", 
        "st" : "unknown", 
    }
]
}
{ 
"_id" : "asdfasdsf2123412324poio12323n2134e",  
"info" : [
    {
        "dates" : [
            {
                "date" : ISODate("2017-01-28T22:00:00.000+0000")
            }
        ], 
        "cm" : "not_set", 
        "ci" : "Toronto", 
        "co" : "Canada", 
        "dev" : "mobile", 
        "lan" : "en", 
        "st" : "Ontario", 
    }
]
}
{ 
"_id" : "asdfasdsf2123412324poio12323n2134f",  
"info" : [
    {
        "dates" : [
            {
                "date" : ISODate("2016-04-28T22:00:00.000+0000")
            }
        ], 
        "cm" : "not_set", 
        "ci" : "Toronto", 
        "co" : "Canada", 
        "dev" : "mobile", 
        "lan" : "en", 
        "st" : "Ontario", 
    }
]
}
{ 
"_id" : "asdfasdsf2123412324poio12323n2134g",  
"info" : [
    {
        "dates" : [
            {
                "date" : ISODate("2017-01-28T22:00:00.000+0000")
            }
        ], 
        "cm" : "not_set", 
        "ci" : "Toronto", 
        "co" : "Canada", 
        "dev" : "mobile", 
        "lan" : "en", 
        "st" : "Ontario", 
    }
]
}
{ 
"_id" : "asdfasdsf2123412324poio12323n2134h",  
"info" : [
    {
        "dates" : [
            {
                "date" : ISODate("2017-02-21T00:00:00.000+0000")
            }
        ], 
        "cm" : "not_set", 
        "ci" : "Athens", 
        "co" : "Greece", 
        "dev" : "desktop", 
        "lan" : "sq", 
        "st" : "Attica", 
    }, 
    {
        "dates" : [
            {
                "date" : ISODate("2017-04-23T21:00:00.000+0000")
            }, 
            {
                "date" : ISODate("2017-04-23T13:00:00.000+0000")
            }, 
            {
                "date" : ISODate("2017-04-22T18:00:00.000+0000")
            }, 
            {
                "date" : ISODate("2017-04-22T12:00:00.000+0000")
            }, 
            {
                "date" : ISODate("2017-04-21T12:00:00.000+0000")
            }
        ], 
        "cm" : "not_set", 
        "ci" : "Athens", 
        "co" : "Greece", 
        "dev" : "desktop", 
        "lan" : "en", 
        "st" : "Attica", 
    }
]
}

测试集合有一个索引

db.test.createIndext({"info.dates.date":-1});

我正在执行一个看起来像

的简单查找查询
db.test.find(
        {"info":{$elemMatch:{
          "dates":{$elemMatch:{
            "date":{
              $gte:ISODate("2017-03-01T00:00:00.000+0000"),
              $lte:ISODate("2017-03-31T00:00:00.000+0000")
            }}}}}});

它返回一个绝对正常的文档,但问题是,它扫描了5个文档(我可以通过 explain() 看到)这比它应该扫描更多。 根据我的理解,如果我在日期字段上创建了一个索引,那么它应该只扫描那些在查询范围内给出日期的文档,但事实并非如此。

如果我们更改所有不在 ISODate中的文件的日期(" 2017-03-01T00:00:00.000 + 0000"),这一点很奇怪。 - ISODate(" 2017-03-31T23:59:59.999 + 0000") 范围,大于ISODate的日期(" 2017-03-31T23:59 :59.999 + 0000")然后查询将返回一个文档,它将只扫描一个文档。

0 个答案:

没有答案