134

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()
4

3 回答 3

197

从 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 Frameworkexplain选项提供有关如何处理管道的信息,但不支持与查询executionStats模式相同级别的详细信息find()。如果您专注于优化初始查询执行,您可能会发现使用verbosityfind().explain()查看等效查询是有益的。executionStatsallPlansExecution

在 MongoDB 问题跟踪器中有一些相关的功能请求需要关注/支持,以帮助优化/配置聚合管道:

于 2012-10-03T05:58:13.653 回答
30

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

您需要做的就是添加说明:true

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

感谢 Rafa,我知道即使在 2.4 中也可以这样做,但只能通过runCommand(). 但是现在您也可以使用聚合。

于 2013-10-26T01:16:21.407 回答
21

聚合框架

聚合框架是一组分析工具MongoDB,允许我们对一个或多个集合中的文档运行各种类型的报告或分析。基于管道的想法。我们从MongoDB集合中获取输入,并通过一个或多个阶段传递来自该集合的文档,每个阶段对其输入执行不同的操作。每个阶段都将其作为输出之前的任何阶段作为输入。所有阶段的输入和输出都是文档流。每个阶段都有它所做的特定工作。它期待一种特定形式的文档并产生一个特定的输出,它本身就是一个文档流。在管道结束时,我们可以访问输出。

聚合框架阶段

一个单独的阶段是一个数据处理单元。每个阶段一次将一个文档流作为输入,一次处理一个文档并生成文档的输出流。再次,一次一个。每个阶段都提供了一组旋钮或可调参数,我们可以控制这些旋钮或可调参数来参数化阶段以执行我们感兴趣的任何任务。因此,一个阶段执行一项通用任务——某种通用任务,并为我们正在处理的特定文档集参数化该阶段。以及我们希望那个阶段对这些文件做什么。这些可调参数通常采用我们可以提供的运算符的形式,它们将修改字段、执行算术运算、重塑文档或执行某种累积任务以及许多其他事情。很多时候,我们的情况是

在单个管道中多次使用相同类型的阶段

例如,我们可能希望执行一个初始过滤器,这样我们就不必将整个集合传递到我们的管道中。但是,稍后,经过一些额外的处理,想要再次使用一组不同的标准进行过滤。因此,回顾一下,管道与MongoDB集合一起工作。它们由阶段组成,每个阶段对其输入执行不同的数据处理任务,并生成文档作为输出以传递到下一个阶段。最后在管道输出的最后产生我们可以在我们的应用程序中做一些事情。在许多情况下,有必要在单个管道中多次包含相同类型的阶段。

于 2016-09-15T19:29:46.517 回答