无法获取覆盖查询以仅在mongodb中使用索引

时间:2013-01-07 05:54:06

标签: mongodb indexing mongoid

我正在尝试使用覆盖索引在我的使用mongodb的应用上实现词干文本搜索。

我有以下索引集:

ensureIndex({st: 1, n: 1, _id: 1});

但是当我在查询中运行explain()时,无论我做什么,我都无法将indexOnly读为true。

db.merchants.find({st: "Blue"}, {n:1,_id:1}).explain()
{
    "cursor" : "BtreeCursor st_1_n_1__id_1",
    "nscanned" : 8,
    "nscannedObjects" : 8,
    "n" : 8,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : true,
    "indexOnly" : false,
    "indexBounds" : {
        "st" : [
            [
                "Blue",
                "Blue"
            ]
        ],
        "n" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ],
        "_id" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    }
}

我已经知道索引中键的顺序不知何故。例如,如果我使用{_id,n:1,st:1},则根本不使用此索引来执行查询。我还读到了一些文件太少,因为多个策略同样快,因此可以用explain()触发不可预测的行为。但在这种情况下,我看到它使用正确的索引,但它不仅仅使用索引。这是怎么回事?

我正在使用mongoid,而mongo 2.0.8我相信。

更新:

切换到使用Mongoid v3.1.4和mongod v2.2

以下是mongod从mongoid看到的查询:Mon Jul 15 10:47:26 [conn14] runQuery名为spl_development.merchants {$ query:{st:{$ regex:“cr”,$ options:“i “}},$ explain:true} Mon 7月15日10:47:26 [conn14]查询spl_development.merchants查询:{$ query:{st:{$ regex:”cr“,$ options:”i“}}, $ explain:true} ntoreturn:0 keyUpdates:0 lock(micros)r:212 nreturned:1 reslen:393 0ms

因此投影不会被发送到mongod层,只是在应用层中处理它。不理想!

这已被认为是mongoid中的一个错误,可以在这里跟踪: https://github.com/mongoid/mongoid/issues/3142

2 个答案:

答案 0 :(得分:8)

我希望您的查询不能使用覆盖索引,因为您有一个包含在索引中的数组的字段。这在"isMultiKey" : true的解释中提出。

如文档(Create Indexes that Support Covered Queries)中所述:

  

如果集合中任何文档中的任何索引字段包含数组,则MongoDB无法使用覆盖查询。如果索引字段是数组,则索引将成为多键索引,并且不支持覆盖查询。

答案 1 :(得分:1)

我无法重现2.2.2中的问题,但将.sort({n: 1, _id: 1})添加到链中。因为你没有排序,你要求mongo希望使用的任何find命令中的文档,如果这与命令中的顺序(例如$natural)不匹配它仍然需要阅读文档。

db.merchants.find({st: "Blue"}, {n:1,_id:1}).sort({n: 1, _id: 1}).explain()