Mongodb查询不使用索引

时间:2018-09-04 18:22:50

标签: mongodb

我在mongo集合上设置了复合索引,无论我如何具体定位前缀,我都无法获得使用它的查询。

如何创建索引:

db.collection.createIndex({"insert_time":-1,"name":"text"},{background: true})

索引规范输出:

db.collection.getIndexes()
[
{
    "v" : 2,
    "key" : {
        "_id" : 1
    },
    "name" : "_id_",
    "ns" : "db.collection"
},
{
    "v" : 2,
    "key" : {
        "insert_time" : -1,
        "_fts" : "text",
        "_ftsx" : 1
    },
    "name" : "insert_time_-1_name_text",
    "ns" : "db.collection",
    "background" : true,
    "weights" : {
        "name" : 1
    },
    "default_language" : "english",
    "language_override" : "language",
    "textIndexVersion" : 3
}
]

但是当我在insert_time上运行最简单的查询时,explain()告诉我,获胜的计划是进行COLLSCAN,而不使用任何索引:

db.collection.find({"insert_time": ISODate("2018-08- 
05T19:00:00Z")}).explain()
{
"queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "db.collection",
    "indexFilterSet" : false,
    "parsedQuery" : {
        "insert_time" : {
            "$eq" : ISODate("2018-08-05T19:00:00Z")
        }
    },
    "winningPlan" : {
        "stage" : "COLLSCAN",
        "filter" : {
            "insert_time" : {
                "$eq" : ISODate("2018-08-05T19:00:00Z")
            }
        },
        "direction" : "forward"
    },
    "rejectedPlans" : [ ]
},
"serverInfo" : {
    "host" : "foo",
    "port" : 0000,
    "version" : "3.4.10",
    "gitVersion" : "078f28920cb24de0dd479b5ea6c66c644f6326e9"
},
"ok" : 1
}

即使索引被指定为“复合索引”,但我的理解是我应该能够通过“前缀”进行搜索,在这种情况下,insert_time是。关于mongo为什么不使用我的索引的任何想法?

2 个答案:

答案 0 :(得分:3)

text的索引是sparse by default

索引中的非文本索引字段不引用text索引(reference)中的文档

  

对于包含文本索引键以及其他类型的键的复合索引,只有文本索引字段才能确定索引是否引用文档。其他键不能确定索引是否引用文档。

=>在没有文本索引字段的情况下使用前缀索引时,结果可能不完整

关于这种情况(sparse Index and Incomplete Results),MongoDB指出:

  

如果索引稀疏会导致查询和排序操作的结果集不完整,则除非hint()明确指定索引,否则MongoDB不会使用该索引。

如果使用hint('yourTextIndexName'),则使用索引。

因此,OP的情况是预期的行为,但没有充分记录。

答案 1 :(得分:0)

这感觉像是个错误。

我能够使用MongoDB 3.6.7重现您在自己的数据集上看到的行为。我暗示了有问题的索引,并且查询计划程序无法在前缀字段上绑定(我在year上进行了直接匹配):

"indexBounds" : {
                    "year" : [
                        "[MinKey, MaxKey]"
                    ],
                    "_fts" : [
                        "[MinKey, MaxKey]"
                    ],
                    "_ftsx" : [
                        "[MinKey, MaxKey]"
                    ]
                },

compound text indexes的文档中没有任何语句表明无法使用文本索引的前缀部分。 index prefixes上的文档也没有包含有关限制的任何语言。

编辑:

我创建了一个server ticket来报告此行为,并尝试获取有关此错误或错误的更多信息。