首页 > 解决方案 > Mongo 视图未显示与目标集合中相同的索引速度改进

问题描述

我创建了一个 mongo 视图,它基本上针对“帐户”集合上的文档 - 特别是“transactions.amount.balance”的值大于零的地方。所以看起来像这样:

{"transactions.amounts.balance": { $gt : 0 }}

现在,因为结果需要很长时间才能返回,所以我在此视图使用的集合中的该字段上添加了一个索引。随后,当我在集合上运行此查询时,现在返回的结果要快得多——比如在添加索引之前不到一秒而不是 9 秒。

但是,话虽如此,我似乎没有注意到我创建的 mongo 视图中的相同性能改进,除其他外,它再次在同一集合上重新创建相同的查询。

我的理解是,视图将继承在它所针对的集合上创建的所有索引。那么,如果是这样,为什么我在 mongo 视图中没有看到任何性能改进?我错过了什么吗?

顺便说一句,当我检查我的聚合管道的每个阶段的输入和输出时,果然,这是需要大约 9 秒才能返回结果的那个:

{ "transactions.amounts.balance" : { "$gt" : 0.0 } }

为什么在我看来这个查询步骤比直接在它所针对的集合上运行时慢得多?我还有什么可以帮助加快执行此查询步骤的吗?

以下是我的 mongo 视图中聚合管道的前几个步骤:

db.accounts.aggregate(

  // Pipeline
  [
    // Stage 1
    {
      $unwind: {
        "path": "$transactions"
      }
    },

    // Stage 2
    {
      $match: {
        "transactions.amounts.balance": {
          "$gt": 0.0
        }
      }
    },

    // Stage 3
    {
      $addFields: {
        "openBalance": "$transactions.amounts.balance"
      }
    }

标签: mongodbindexingaggregation-framework

解决方案


根据文档$match只有在没有其他先前阶段的情况下才使用索引。

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

由于您首先展开文档,$match因此也不会使用您应该从explain()计划中看到的索引。

根据您的数据,特别是,如果您有很多文档在数组中不包含匹配条目,则简单地复制过滤器并将其放在管道的最开头以transactions.amounts.balance提高性能可能会有所帮助$match删除一些文件。在最好的情况下(同样,这取决于您的数据),生成的文档数量将足够低,以便第二$match阶段不再损害性能。


推荐阅读