我创建了一个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"
}
}
答案 0 :(得分:2)
根据documentation,$match
只会使用索引,如果它没有其他前一阶段使用。
如果在管道的最开头放置$ match,则查询 可以利用像任何其他db.collection.find()或 db.collection.findOne()。
由于您首先展开文档,$match
将不会使用您应该从explain()
计划中看到的索引。
具体而言,根据您的数据,如果您在transactions.amounts.balance
数组中包含大量不包含匹配条目的文档,则只需复制$match
过滤器,就性能而言可能会有所帮助并将一个放在管道的最开头,以便删除一些文档。在最好的情况下(再次,这取决于您的数据),最终的文档数量将足够低,以便第二个$match
阶段不再影响性能。