无法使用复合索引创建覆盖查询

时间:2013-11-06 18:23:19

标签: mongodb

我的索引:

{
        "v" : 1,
        "key" : {
                "a" : 1,
                "b" : 1,
                "c" : 1
        },
        "ns" : "Pepper.test",
        "name" : "a_1_b_1_c_1"
}

样本记录:

{ "_id" : ObjectId("527a8477a868a04479a56a56"), "a" : 1, "b" : 1, "c" : 1, "x" : -1 }

我的查询:

db.test.find({a: 1, b: 1, c: 1},{_id: 0, x:0})

来自explain()的输出:

{
        "cursor" : "BtreeCursor a_1_b_1_c_1",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 1,
        "nscanned" : 1,
        "nscannedObjectsAllPlans" : 1,
        "nscannedAllPlans" : 1,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 0,
        "indexBounds" : {
                "a" : [
                        [
                                1,
                                1
                        ]
                ],
                "b" : [
                        [
                                1,
                                1
                        ]
                ],
                "c" : [
                        [
                                1,
                                1
                        ]
                ]
        },
        "server" : "ip-x-x-x-x:27017"
}

从文档中看起来像这样的测试应该在解释中将“indexOnly”报告为true,但事实并非如此。我做错了什么,或者误解了被覆盖查询的限制?此数据集仅是显示问题的示例,但它与我的实际数据和索引具有相同的基本结构。

进行测试,如果我完全从我的数据中删除x字段,并指定包含a,b,c并排除_id它有效。如果您的数据集中的任何字段不是索引的一部分,我似乎无法执行覆盖索引。我尝试包括a,b,c,并排除_id和x,但是mongo提供了一个错误说明:

  

“$ err”:“您目前无法混合包含和排除字段。   如果这是一个问题,请联系我们。“

2 个答案:

答案 0 :(得分:2)

此查询的explain显示"indexOnly": true

db.test.find({a: 1, b: 1, c: 1}, {_id: 0, a: 1, b: 1, c: 1})

正如@Sammaye在评论中提到的那样,您的投影需要指定一整套包含字段,因为只排除知道不在索引中的字段这意味着你的收藏中没有一些文档与其他字段不在索引中。

答案 1 :(得分:1)

如果您已选择排除“_id”,则无法选择排除任何其他内容。