【问题标题】:Does second $match use index第二个 $match 是否使用索引
【发布时间】:2013-09-03 16:39:03
【问题描述】:

来自 MongoDB docs:

尽可能早地将 $match 放在聚合管道中。因为 $match 限制了聚合管道中的文档总数,所以早期的 $match 操作最大限度地减少了管道的处理量。

如果您将 $match 放在管道的最开头,则查询可以像任何其他 db.collection.find() 或 db.collection.findOne() 一样利用索引。

给定查询

db.articles.aggregate( [ 
                    { $match : {date : {$gt: now, $lte: later } } },
                    { $match : { score : { $gt : 70, $lte : 90 } } },
                    { $group: { _id: null, count: { $sum: 1 } } }
                   ] );

在哪里(当然),现在和以后代表格式正确的日期,

聚合框架是否将索引用于第二个匹配项(如果可用),还是只有聚合管道中的第一个匹配项才有资格使用索引。

查询是否会执行得更好:

db.articles.aggregate( [ 
                        { $match : {date : {$gt: now, $lte: later }, score : { $gt : 70, $lte : 90 } } },
                        { $group: { _id: null, count: { $sum: 1 } } }
                   ] );

假设存在涵盖日期和分数的索引?

【问题讨论】:

  • 它是复合索引吗,如果是,那么前缀将阻止它工作
  • 为了便于讨论,我们假设集合有一个单独的日期和分数索引,以及日期+分数
  • 我会假设由于没有发生任何组等,因此 MongoDB 应该为两者使用索引,但是我实际上不确定它是如何以这种方式编程的,它可能无法检测到这一点,这真的是内部,当然后一个查询会好 100 倍
  • 看起来我们将“很快”获得explain 聚合:jira.mongodb.org/browse/SERVER-4504
  • @WiredPrairie 确实会省去查看源代码,希望很快就会出现

标签: mongodb aggregation-framework


【解决方案1】:

不,MongoDB(从 v2.4.6 开始)只会在管道中的第一个 $match 上使用索引。

对于您发布的第二个聚合查询,只要您有一个关于日期和分数的复合索引,该索引就会用于查询。这应该比您的第一个查询执行得更好。

【讨论】:

  • 这在 v2.6 中有改变吗?而且,如果您在管道中有两个匹配项,例如[{$match:{x:...}},{$match:{y:...}}],并且您在 x 和 y 上有两个单独的索引(并且您不能在 x 和 y 上有一个复合索引,因为 x 是,比方说,一个多键索引并且 y 是一个文本索引),MongoDB 可以为管道中的不同 $match 阶段使用不同的索引吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-29
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
  • 2017-12-20
相关资源
最近更新 更多