首页 文章

Mongodb解释聚合框架

提问于
浏览
86

MongoDB中的Aggregation框架是否有解释功能?我在文档中看不到它 .

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

我知道发现你就是这么做的

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

3 回答

  • 27

    从MongoDB 3.0版开始,只需更改订单即可

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

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

    会给你想要的结果(文件here) .

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

    解释:是的

    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 阶段启动管道以限制对相关文档的处理 .

    • 确保efficient index支持初始 $match / $sort 阶段 .

    • 使用 $match$limit$skip 提前过滤数据 .

    • 尽量减少不必要的阶段和文档操作(如果需要复杂的聚合体操,可能会重新考虑您的模式) .

    • 如果已升级MongoDB服务器,请利用更新的聚合运算符 . 例如,MongoDB 3.4添加了许多new aggregation stages and expressions,包括对使用数组,字符串和构面的支持 .

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

    限制

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

    在MongoDB问题跟踪器中有一些相关的功能请求需要观察/ upvote,以获取更详细的执行统计数据,以帮助优化/分析聚合管道:

  • 14

    从版本 2.6.x mongodb开始允许用户执行explain with aggregation framework .

    您需要做的就是添加explain:true

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

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

  • 129

    The Aggregation framework

    聚合框架是 MongoDB 中的一组分析工具,允许我们对一个或多个集合中的文档运行各种类型的报告或分析 . 基于管道的想法 . 我们从 MongoDB 集合中获取输入,并将该集合中的文档通过一个或多个阶段传递,每个阶段对其执行不同的操作's inputs. Each stage takes as input whatever the stage before it produced as output. And the inputs and outputs for all stages are a stream of documents. Each stage has a specific job that it does. It'期望特定形式的文档并生成特定输出,这本身就是文档流 . 在管道的最后,我们可以访问输出 .

    aggregation framework stage

    单个阶段是数据处理单元 . 每个阶段一次一个地接受文档流,每次处理一个文档并产生文档的输出流 . 再一次,一次一个 . 每个阶段都提供一组旋钮或可调参数,我们可以控制这些旋钮或可调参数来参数化舞台以执行我们感兴趣的任务 . 因此,一个阶段执行一般任务 - 某种通用任务,并为我们正在使用的特定文档集参数化阶段 . 而这正是我们希望那个阶段与这些文件做的事情 . 这些可调参数通常采用我们可以提供的运算符的形式,它将修改字段,执行算术运算,重塑文档或执行某种累积任务以及各种其他事情 . 通常情况下,我们希望在a中多次包含相同类型的舞台单一管道 .

    same type of stage multiple times within a single pipeline

    例如我们可能希望执行初始过滤器,以便我们不必将整个集合传递到我们的管道中 . 但是,稍后,在进行一些额外的处理之后,想要使用一组不同的标准再次过滤 . 因此,回顾一下,管道与 MongoDB 集合一起工作 . 他们're composed of stages, each of which does a different data processing task on it'输入并生成文档作为输出传递给下一个阶段 . 最后,在管道输出结束时,我们可以在应用程序中执行某些操作 . 在许多情况下,有必要在单个管道中多次包含相同类型的阶段 .

相关问题