Mongodb解释聚合框架


118

MongoDB中的聚合框架有解释功能吗?我在文档中看不到它。

如果没有其他检查方法,则查询如何在聚合框架内执行?

我知道找到你就做

db.collection.find().explain()

但是使用聚合框架,我得到一个错误

db.collection.aggregate(
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { 
        $group: 
        { 
            _id : { id: "$_id"},
            "count": { $sum:1 } 
        }
    },
    { $sort: {"count":-1}}
).explain()

Answers:


172

从MongoDB 3.0版开始,只需更改顺序即可

collection.aggregate(...).explain()

collection.explain().aggregate(...)

将为您提供所需的结果(此处的文档)。

对于> = 2.6的旧版本,您将需要使用该explain选项进行聚合管道操作

explain:true

db.collection.aggregate([
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { $group: { 
        _id : "$_id",
        count: { $sum:1 } 
    }},
    {$sort: {"count":-1}}
  ],
  {
    explain:true
  }
)

与聚合框架的一个重要考虑是,索引只能用于获取用于管道的初始数据(例如使用情况 $match$sort$geonear在管道的开始处),以及随后的 $lookup$graphLookup阶段。一旦将数据提取到聚合管道中进行处理(例如,通过诸如$project$unwind和等阶段$group),则将在内存中进行进一步的操作(如果allowDiskUse设置了该选项,则可能使用临时文件)。

优化管道

通常,您可以通过以下方法优化聚合管道:

  • 启动一个$match阶段以将处理限制在相关文档中。
  • 确保初始$match/ $sort阶段得到有效索引的支持。
  • 过滤数据早期使用$match$limit$skip
  • 最小化不必要的阶段和文档操作(如果需要复杂的聚合体操,则可能重新考虑您的架构)。
  • 如果您已经升级了MongoDB服务器,请利用更新的聚合运算符。例如,MongoDB 3.4添加了许多新的聚合阶段和表达式,包括对处理数组,字符串和构面的支持。

根据您的MongoDB服务器版本,还会自动进行多种聚合管道优化。例如,相邻阶段可以合并和/或重新排序以改善执行,而不会影响输出结果。

局限性

与MongoDB 3.4一样,Aggregation Framework explain选项提供有关如何处理管道的信息,但不支持与查询executionStats模式相同的详细程度find()。如果您专注于优化初始查询的执行,则可能会发现find().explain()executionStatsallPlansExecution详细检查等效查询会有所帮助。

MongoDB问题跟踪器中有一些相关的功能请求需要监视/更新,这些请求涉及更详细的执行统计信息,以帮助优化/配置聚合管道:


感谢您提供的信息,看看是否可以进行任何更改。
SCB 2012年

如果没有$sort对象是管道数组中?
JohnnyHK 2014年

@JohnnyHK:是的。某些人正在错误地“纠正”答案:)。
Stennie 2014年

但这并没有提供“ executionStats”
Kanagavelu Sugumar

1
@KanagaveluSugumar我已经更新了答案,澄清了Aggregation Framework的explain限制以及对其他执行统计信息的相关功能请求。
Stennie

29

2.6.x版本开始,mongodb允许用户使用聚合框架进行解释

您需要做的只是添加解释:true

db.records.aggregate(
  [ ...your pipeline...],
  { explain: true }
)

多亏了Rafa,我知道即使在2.4版本中也可以做到这一点,但只能通过 runCommand()。但是现在您也可以使用聚合。


5
实际上,您可以db.collection.runCommand('aggregate', {pipeline: [PIPELINE], explain: true})从MongoDB 2.2开始解释聚合。
拉法

1
没错,在2.2和2.4中,您只能通过runCommand解释聚合。感谢您的支持。
2013年

3
尽管该选项在技术上通过2.6之前的runCommand存在,但不能保证会产生正确的结果,因此不建议使用。您实际上应该只在2.5.3或更高版本中使用此功能(并希望在2.6生产版本之前可能仍然存在一些错误)。
Stennie 2013年

20

汇总框架

聚合框架是其中的一组分析工具MongoDB,使我们可以对一个或多个集合中的文档运行各种类型的报告或分析。基于管道的想法。我们从一个MongoDB集合中获取输入,并通过一个或多个阶段传递该集合中的文档,每个阶段对其输入执行不同的操作。无论哪个阶段产生输出,每个阶段都将其作为输入。所有阶段的输入和输出都是文件流。每个阶段都有其特定的工作。它期望一种特定形式的文档并产生特定的输出,该输出本身就是一系列文档。在管道的最后,我们可以访问输出。

聚合框架阶段

单个阶段是数据处理单元。每个阶段一次输入一个文档流,一次处理一个文档,并生成输出文档流。再一次,一次。每个阶段都提供了一组旋钮或可调参数,我们可以控制它们来参数化该阶段以执行我们感兴趣的任何任务。因此,阶段执行通用任务-某种通用任务,并为正在使用的特定文档集参数化阶段。正是我们希望该阶段与这些文件相关的事情。这些可调参数通常采用我们可以提供的运算符的形式,这些运算符将修改字段,执行算术运算,调整文档形状或执行某种累加任务以及许多其他事情。通常情况下,

在单个管道中多次执行相同类型的阶段

例如,我们可能希望执行初始过滤,这样就不必将整个集合传递到我们的管道中。但是,随后再进行一些附加处理后,希望再次使用一组不同的条件进行过滤。因此,总而言之,管道与MongoDB集合一起工作。它们由阶段组成,每个阶段对输入执行不同的数据处理任务,并生成文档作为输出传递到下一个阶段。最后,在管道输出的最后,我们可以在应用程序中执行某些操作。在许多情况下,有必要在单个管道中多次包含相同类型的阶段。


谢谢,这有助于更好地理解。
阿伦·普拉塔普·辛格
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.