Mongodb查询没有';不使用索引

Mongodb查询没有';不使用索引,mongodb,Mongodb,我在mongo集合上设置了一个复合索引,无论我如何专门针对前缀,我都无法让查询使用它 如何创建索引: db.collection.createIndex({"insert_time":-1,"name":"text"},{background: true}) 索引规格输出: db.collection.getIndexes() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_", "ns

我在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\u time
是。关于mongo为什么不使用我的索引有什么想法吗?

这感觉像是一个bug

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

的文档不包含任何说明无法使用文本索引的前缀部分的语句。上的文档也不包含任何有关限制的语言

编辑:


我创建了一个报告此行为的工具,并尝试获取有关这是预期的还是错误的更多信息

文本
索引为

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

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

=>如果使用前缀索引而不使用文本索引字段,则结果可能不完整

关于这个案例(),MongoDB声明:

如果稀疏索引会导致查询和排序操作的结果集不完整,MongoDB将不会使用该索引,除非提示()显式指定该索引

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


因此OP的情况是一种预期行为,但没有很好的文档记录。

关于复合文本索引如何工作,确实没有太多的解释,但我的直觉是,它仍然是每个文本标记一个索引项。这意味着您不能只查询
insert\u time
,因为这将无法找到文本字段完全为空的文档。前缀列仅在有效限制文本搜索顶部时才有用。添加类似于
和文本有任何标记的内容可以使其工作吗?但我不知道该怎么写,我也觉得文本索引只能用于文本搜索。不过,我本以为这会记录在复合文本索引下。此外,此语句似乎(但不是)表明它们可以用于非文本搜索:`如果复合文本索引包含文本索引键之前的键,则要执行$text搜索,查询谓词必须包含前面键上的相等匹配条件。`(来自上面的复合文本索引链接)。请参阅我的编辑;我创建了一个服务器票证,试图确认这是否是预期的ạ新罕布什尔州奎伊ế唐古伊ễn找到一些文档来确认这是预期的行为。这是正确的答案。这一问题似乎与以下问题重复:
"indexBounds" : {
                    "year" : [
                        "[MinKey, MaxKey]"
                    ],
                    "_fts" : [
                        "[MinKey, MaxKey]"
                    ],
                    "_ftsx" : [
                        "[MinKey, MaxKey]"
                    ]
                },