MongoDB复合索引实际上如何工作?

时间:2019-04-23 18:03:05

标签: mongodb mongodb-indexes

我在mongodb中创建复合索引,发现了奇怪的行为。 我创建了一个索引:

db.getCollection('Subject').createIndex({a:1, b:2, c:3})

它创建了一个名为a_1_b_2_c_3的索引。

现在,当我使用mongo find命令时:

db.getCollection('Subject').find({a:1, b:2, c:3}) //it works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({a:1, b:2}) //this also works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({a:1, c:2}) //this also works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({b:1, c:2}) //But this command doesn't uses the index `a_1_b_2_c_3`.

任何人都可以让我知道为什么发生这种情况吗?

2 个答案:

答案 0 :(得分:1)

这是由于index prefixes造成的。索引{a:1, b:1, c:1}的前缀为{ a: 1 }{ a: 1, b: 1},因此在这些字段上包含过滤器的查询将使用索引。

从概念上讲,可以将索引视为一个B树,该B树以a上的过滤器开头,并在较低级别的bc上具有子树。较早的查询可以轻松地从树的顶部开始,然后向下进行,而最后一个查询({b:1, c:2})不会有一个简单的起点。

答案 1 :(得分:0)

如果您仍要强制MongoDB使用您的索引,则可以按以下方式伪造查询(我已经对其进行了测试)。在这种情况下,我假设您的集合中“ a”的值仅是正整数。

db.Subject.explain("executionStats").find({a:{$gt:-1}, b:1, c:2})

这可能会影响其他应用程序功能,或者如果这种查询是标准模式,则创建一个专用索引来解决该查询。