Mongodb解释聚合框架

Posted

技术标签:

【中文标题】Mongodb解释聚合框架【英文标题】:Mongodb Explain for Aggregation framework 【发布时间】:2012-09-24 00:03:36 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

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

会给你想要的结果(文档here)。

对于 >= 2.6 的旧版本,您需要使用 explain option for aggregation pipeline operations

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 阶段由 efficient index 支持。 使用 $match$limit$skip 及早过滤数据。 尽量减少不必要的阶段和文档操作(如果需要复杂的聚合体操,可能会重新考虑您的架构)。 如果您已升级 MongoDB 服务器,则可以利用更新的聚合运算符。例如,MongoDB 3.4 添加了许多new aggregation stages and expressions,包括对使用数组、字符串和构面的支持。

还有许多 Aggregation Pipeline Optimizations 会根据您的 MongoDB 服务器版本自动发生。例如,可以合并和/或重新排序相邻阶段以改进执行而不影响输出结果。

限制

在 MongoDB 3.4 中,聚合框架 explain 选项提供有关如何处理管道的信息,但不支持与 find() 查询的 executionStats 模式相同级别的详细信息。如果您专注于优化初始查询执行,您可能会发现使用 executionStats or allPlansExecution verbosity 查看等效的 find().explain() 查询是有益的。

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

SERVER-19758: Add "executionStats" and "allPlansExecution" explain modes to aggregation explain SERVER-21784: Track execution stats for each aggregation pipeline stage and expose via explain SERVER-22622: Improve $lookup explain to indicate query plan on the "from" collection

【讨论】:

感谢您的信息,看看我是否可以进行任何更改。 $sort 对象不应该在管道数组中吗? @JohnnyHK:是的。一些善良的人正在错误地“纠正”答案:)。 但这并没有给出“executionStats” @KanagaveluSugumar 我已经更新了答案,澄清了聚合框架explain 的限制以及其他执行统计信息的相关功能请求。【参考方案2】:

从版本2.6.x开始,mongodb允许用户做explain with aggregation framework。

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

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

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

【讨论】:

其实从 MongoDB 2.2 起,你就可以用db.collection.runCommand('aggregate', pipeline: [PIPELINE], explain: true) 来解释聚合了。 你说得对,2.2和2.4只能通过runCommand来解释聚合。感谢您的支持。 虽然该选项在技术上通过 2.6 之前的 runCommand 存在,但不能保证产生正确的结果,不应提倡。你真的应该只在 2.5.3 或更高版本中使用它(并且预计在 2.6 生产版本之前可能仍然存在一些错误)。【参考方案3】:

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

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

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

【讨论】:

谢谢,这有助于更好地理解。

以上是关于Mongodb解释聚合框架的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB: 聚合框架

MongoDB、时间序列和聚合框架

MongoDB——聚合管道

MongoDB——聚合管道

从 MongoDB 聚合到 Spring Boot 聚合框架

在 MongoDB 聚合框架中计算中位数