Mongo View在目标集合

时间:2018-04-26 18:47:03

标签: mongodb indexing aggregation-framework

我创建了一个mongo视图,它基本上针对“accounts”集合上的文档 - 特别是“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"
      }
    }

1 个答案:

答案 0 :(得分:2)

根据documentation$match只会使用索引,如果它没有其他前一阶段使用。

  

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

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

具体而言,根据您的数据,如果您在transactions.amounts.balance数组中包含大量不包含匹配条目的文档,则只需复制$match过滤器,就性能而言可能会有所帮助并将一个放在管道的最开头,以便删除一些文档。在最好的情况下(再次,这取决于您的数据),最终的文档数量将足够低,以便第二个$match阶段不再影响性能。