为什么indexOnly属性对于此覆盖查询为false

时间:2014-09-03 05:16:14

标签: mongodb mongodb-query

我有一个带有字段_id,名称,年龄,日期

的测试数据库

索引:

[
    {
            "v" : 1,
            "key" : {
                    "_id" : 1
            },
            "name" : "_id_",
            "ns" : "blogger.users"
    },
    {
            "v" : 1,
            "key" : {
                    "name" : 1,
                    "age" : 1
            },
            "name" : "name_1_age_1",
            "ns" : "blogger.users"
    },
    {
            "v" : 1,
            "key" : {
                    "age" : 1,
                    "name" : 1
            },
            "name" : "age_1_name_1",
            "ns" : "blogger.users"
    }
]

运行以下查询时:

> db.users.find({"name":"user10"},{"_id":0,"date":0})
     .explain()

我得到以下信息:

{
    "cursor" : "BtreeCursor name_1_age_1",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 1,
    "nscanned" : 1,
    "nscannedObjectsAllPlans" : 2,
    "nscannedAllPlans" : 2,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {
            "name" : [
                    [
                            "user10",
                            "user10"
                    ]
            ],
            "age" : [
                    [
                            {
                                    "$minElement" : 1
                            },
                            {
                                    "$maxElement" : 1
                            }
                    ]
            ]
    },
    "server" : "Johny-PC:27017",
    "filterSet" : false

}

没有解释结果是:

{ "name" : "user10", "age" : 68 }

即使这是带有正确投影的覆盖查询,indexOnly字段仍为false。我也试过使用提示明确提供索引,但没有改变。在这种情况下,nscannedObjectsAllPlansnscannedAllPlans的值为1,因为查询不会尝试其他索引。

1 个答案:

答案 0 :(得分:3)

查询是" indexOnly"或"涵盖"返回的唯一字段必须包含在索引中。因此,即使您有" name_1_age_1"的索引,查询引擎仍然希望被告知"您想要的唯一字段是索引中的字段。在你检查之前,它不知道这个文件:

db.users.find({"name":"user10"},{"_id":0, "name": 1, "age": 1 }).explain()

那将返回" indexOnly"因为查询引擎知道所选索引包含输出所需的所有字段。因此,如果还有其他字段要返回,则无需返回集合。