Mongo部分复合唯一索引 | 未在查询中使用

4
我遇到了一个奇怪的问题。我有一个部分复合唯一索引,定义如下:
createIndex({a: 1, b:1, c: 1}, {unique:1, partialFilterExpression: {c: {$type: "string"}}})
现在,当我执行查询时,按照解释计划,这个索引从未被使用,即使有匹配查询的文档。
将相同的索引更改为稀疏索引而不是部分索引可以解决上述问题,但是稀疏复合唯一索引存在以下问题:dealing-with-mongodb-unique-sparse-compound-indexes Index Is Properly Created Query returns a document Index is not Used

如果集合中只有一个项目,那么这并不奇怪。Atlas工具可能也不是最好的查找位置。相反,您应该使用.explain(true)在shell中查看完整结果。这可能会显示,即使索引被“考虑”,但为了单个结果而放弃了索引,而选择了集合扫描。 - Neil Lunn
实际上集合中有多个项。正如您所看到的,文档已经检查:5。这在更大的集合中也会发生。 - Taha Samad
1
你觉得你能展示一个更加“完整”的例子吗?顺便说一下,请确实使用mongo“shell”,并在这里包含“文本”输出,而不是图片。在帖子中阅读图片真的很困难,而“文本”则更加清晰,我们都可以复制和粘贴数据和输出。这也是您无法通过图片完成的另一件事。 - Neil Lunn
1个回答

5
查询覆盖率 部分索引文档所述:

如果使用部分索引导致结果集不完整,则 MongoDB 不会将其用于查询或排序操作。

为了使用部分索引,查询必须包含筛选表达式(或指定筛选表达式子集的修改后的筛选表达式)作为其查询条件之一。

在您的设置中,创建了一个基于 {c: {$type: "string"}} 的部分索引。
您的查询条件是 {a:"1", b:"p", c:"2"},或者说是三个相等比较({a: eq, b: eq, c: eq})。由于此查询形状不包含对 c$type 筛选,因此查询计划器必须考虑适合该形状的查询应匹配任何数据类型的值,并且部分索引不是可行的完整结果候选项。
以下是一些可以使用您的部分索引的示例查询(使用 MongoDB 3.4.5 进行测试):
// Search on {a, b} with c criteria matching the index filter
db.mydb.find({a:"1", b:"p", c: { $type: "string" } })

// Search on {a,b,c} and use $and to include the type of c
db.mydb.find({a:"1", b:"p", $and: [{ c: "2"} , {c: { $type: "string" }}]})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接