Aggregation Pipeline聚合管道

On this page本页内容

An aggregation pipeline consists of one or more stages that process documents:聚合管道由一个或多个处理文档的阶段组成:

Starting in MongoDB 4.2, you can also update documents with an aggregation pipeline. 从MongoDB 4.2开始,您还可以使用聚合管道更新文档。See Updates with Aggregation Pipeline.请参阅使用聚合管道的更新

Complete Aggregation Pipeline Examples完整的聚合管道示例

This section shows aggregation pipeline examples that use the following pizza orders collection:本节显示了使用以下pizza orders集合的聚合管道示例:

db.orders.insertMany( [
   { _id: 0, name: "Pepperoni", size: "small", price: 19,
     quantity: 10, date: ISODate( "2021-03-13T08:14:30Z" ) },
   { _id: 1, name: "Pepperoni", size: "medium", price: 20,
     quantity: 20, date : ISODate( "2021-03-13T09:13:24Z" ) },
   { _id: 2, name: "Pepperoni", size: "large", price: 21,
     quantity: 30, date : ISODate( "2021-03-17T09:22:12Z" ) },
   { _id: 3, name: "Cheese", size: "small", price: 12,
     quantity: 15, date : ISODate( "2021-03-13T11:21:39.736Z" ) },
   { _id: 4, name: "Cheese", size: "medium", price: 13,
     quantity:50, date : ISODate( "2022-01-12T21:23:13.331Z" ) },
   { _id: 5, name: "Cheese", size: "large", price: 14,
     quantity: 10, date : ISODate( "2022-01-12T05:08:13Z" ) },
   { _id: 6, name: "Vegan", size: "small", price: 17,
     quantity: 10, date : ISODate( "2021-01-13T05:08:13Z" ) },
   { _id: 7, name: "Vegan", size: "medium", price: 18,
     quantity: 10, date : ISODate( "2021-01-13T05:10:13Z" ) }
] )

Calculate Total Order Quantity计算总订单数量

The following aggregation pipeline example contains two stages and returns the total order quantity of medium size pizzas grouped by pizza name:以下聚合管道示例包含两个阶段,并返回按披萨名称分组的中型披萨的总订单量:

db.orders.aggregate( [
   // Stage 1: Filter pizza order documents by pizza size阶段1:按披萨大小筛选披萨订单文档
   {
      $match: { size: "medium" }
   },
   // Stage 2: Group remaining documents by pizza name and calculate total quantity第2阶段:按披萨名称对剩余文件进行分组,并计算总数量
   {
      $group: { _id: "$name", totalQuantity: { $sum: "$quantity" } }
   }
] )

The $match stage:$match阶段:

  • Filters the pizza order documents to pizzas with a size of medium.将披萨订单文档筛选为中等大小的披萨。
  • Passes the remaining documents to the $group stage.将剩余的文档传递到$group阶段。

The $group stage:$group阶段:

  • Groups the remaining documents by pizza name.按批萨名称对其余文档进行分组。
  • Uses $sum to calculate the total order quantity for each pizza name. 使用$sum计算每个披萨名称的总订购量quantityThe total is stored in the totalQuantity field returned by the aggregation pipeline.总计存储在聚合管道返回的totalQuantity字段中。

Example output:示例输出:

[
   { _id: 'Cheese', totalQuantity: 50 },
   { _id: 'Vegan', totalQuantity: 10 },
   { _id: 'Pepperoni', totalQuantity: 20 }
]

Calculate Total Order Value and Average Order Quantity计算总订单价值和平均订单数量

The following example calculates the total pizza order value and average order quantity between two dates:以下示例计算两个日期之间的披萨订单总值和平均订单量:

db.orders.aggregate( [
   // Stage 1: Filter pizza order documents by date range阶段1:按日期范围筛选披萨订单文档
   {
      $match:
      {
         "date": { $gte: new ISODate( "2020-01-30" ), $lt: new ISODate( "2022-01-30" ) }
      }
   },
   // Stage 2: Group remaining documents by date and calculate results第2阶段:按日期将剩余文档分组并计算结果
   {
      $group:
      {
         _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
         totalOrderValue: { $sum: { $multiply: [ "$price", "$quantity" ] } },
         averageOrderQuantity: { $avg: "$quantity" }
      }
   },
   // Stage 3: Sort documents by totalOrderValue in descending order第3阶段:按totalOrderValue降序排列文档
   {
      $sort: { totalOrderValue: -1 }
   }
 ] )

The $match stage:$match阶段:

  • Filters the pizza order documents to those in a date range specified using $gte and $lt.将披萨订单文档筛选为使用$gte$lt指定的日期范围内的文档。
  • Passes the remaining documents to the $group stage.将剩余的文档传递到$group阶段。

The $group stage:$group阶段:

  • Groups the documents by date using $dateToString.使用$dateToString按日期对文档进行分组。
  • For each group, calculates:对于每组,计算:

  • Passes the grouped documents to the $sort stage.将分组的文档传递到$sort阶段。

The $sort stage:$sort阶段:

  • Sorts the documents by the total order value for each group in descending order (-1).按每组的总订单值按降序(-1)对文档进行排序。
  • Returns the sorted documents.返回已排序的文档。

Example output:示例输出:

[
   { _id: '2022-01-12', totalOrderValue: 790, averageOrderQuantity: 30 },
   { _id: '2021-03-13', totalOrderValue: 770, averageOrderQuantity: 15 },
   { _id: '2021-03-17', totalOrderValue: 630, averageOrderQuantity: 30 },
   { _id: '2021-01-13', totalOrderValue: 350, averageOrderQuantity: 10 }
]

Additional Aggregation Pipeline Stage Details其他聚合管道阶段详细信息

An aggregation pipeline consists of one or more stages that process documents:聚合管道由一个或多个处理文档的阶段组成:

  • A stage does not have to output one document for every input document. 阶段不必为每个输入文档输出一个文档。For example, some stages may produce new documents or filter out documents.例如,某些阶段可能会生成新文档或筛选掉文档。
  • The same stage can appear multiple times in the pipeline with these stage exceptions: $out, $merge, and $geoNear.同一阶段可以在管道中多次出现,但有以下阶段例外:$out$merge$geoNear
  • To calculate averages and perform other calculations in a stage, use aggregation expressions that specify aggregation operators. 要计算平均值并在阶段中执行其他计算,请使用指定聚合运算符聚合表达式You will learn more about aggregation expressions in the next section.在下一节中,您将了解有关聚合表达式的更多信息。

For all aggregation stages, see Aggregation Pipeline Stages.有关所有聚合阶段,请参阅聚合管道阶段

Aggregation Pipeline Expressions聚合管道表达式

Some aggregation pipeline stages accept an aggregation expression, which:某些聚合管道阶段接受聚合表达式,该表达式:

Starting in MongoDB 4.4, you can use the $accumulator and $function aggregation operators to define custom aggregation expressions in JavaScript.从MongoDB 4.4开始,您可以使用$accumulator$function聚合运算符在JavaScript中定义自定义聚合表达式。

For all aggregation expressions, see Expressions.有关所有聚合表达式,请参阅表达式

Run an Aggregation Pipeline运行聚合管道

To run an aggregation pipeline, use:要运行聚合管道,请使用:

Update Documents Using an Aggregation Pipeline使用聚合管道更新文档

To update documents with an aggregation pipeline, use:要使用聚合管道更新文档,请使用:

Command命令mongosh Methods方法
findAndModify
update

Other Considerations其他考虑

Aggregation Pipeline Limitations聚合管道限制

An aggregation pipeline has limitations on the value types and the result size. 聚合管道对值类型和结果大小有限制。See Aggregation Pipeline Limits.请参阅聚合管道限制

Aggregation Pipelines and Sharded Collections聚合管道和分片集合

An aggregation pipeline supports operations on sharded collections. 聚合管道支持对分片集合的操作。See Aggregation Pipeline and Sharded Collections.请参阅聚合管道和分片集合

Aggregation Pipelines as an Alternative to Map-Reduce聚合管道作为Map Reduce的替代方案

Starting in MongoDB 5.0, map-reduce is deprecated:从MongoDB 5.0开始,不推荐使用map-reduce

  • Instead of map-reduce, you should use an aggregation pipeline. 应该使用聚合管道,而不是map-reduceAggregation pipelines provide better performance and usability than map-reduce.聚合管道提供了比map-reduce更好的性能和可用性。
  • You can rewrite map-reduce operations using aggregation pipeline stages, such as $group, $merge, and others.您可以使用聚合管道阶段(例如$group$merge等)重写map-reduce操作。
  • For map-reduce operations that require custom functionality, you can use the $accumulator and $function aggregation operators, available starting in version 4.4. 对于需要自定义功能的map-reduce操作,可以使用$accumulator$function聚合运算符,从版本4.4开始提供。You can use those operators to define custom aggregation expressions in JavaScript.可以使用这些运算符在JavaScript中定义自定义聚合表达式。

For examples of aggregation pipeline alternatives to map-reduce, see:有关map reduce的聚合管道替代方案的示例,请参阅:

Learn More了解更多

To learn more about aggregation pipelines, see:要了解有关聚合管道的更多信息,请参阅:

←  AggregationAggregation Pipeline Optimization →