Aggregation Pipeline聚合管道
On this page本页内容
An aggregation pipeline consists of one or more stages that process documents:聚合管道由一个或多个处理文档的阶段组成:
Each stage performs an operation on the input documents.每个阶段对输入文档执行一个操作。For example, a stage can filter documents, group documents, and calculate values.例如,阶段可以筛选文档、对文档进行分组和计算值。The documents that are output from a stage are passed to the next stage.从一个阶段输出的文档将传递到下一个阶段。An aggregation pipeline can return results for groups of documents.聚合管道可以返回文档组的结果。For example, return the total, average, maximum, and minimum values.例如,返回总值、平均值、最大值和最小值。
Starting in MongoDB 4.2, you can update documents with an aggregation pipeline if you use the stages shown in Updates with Aggregation Pipeline.从MongoDB 4.2开始,如果您使用使用聚合管道更新中显示的阶段,则可以使用聚合管道更新文档。
Aggregation pipelines run with the 使用db.collection.aggregate()
method do not modify documents in a collection, unless the pipeline contains a $merge
or $out
stage.db.collection.aggregate()
方法运行的聚合管道不会修改集合中的文档,除非管道包含$merge
或$out
阶段。
Complete Aggregation Pipeline Examples完整的聚合管道示例
This section shows aggregation pipeline examples that use the following pizza 本节显示了使用以下比萨饼orders
collection: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" } }
}
] )
Filters the pizza order documents to pizzas with a将披萨订单文档筛选size
ofmedium
.size: medium
的披萨。Passes the remaining documents to the将剩余的文档传递到$group
stage.$group
阶段。
Groups the remaining documents by pizza按披萨饼name
.name
对剩余文档进行分组。Uses使用$sum
to calculate the total orderquantity
for each pizzaname
.$sum
计算每个披萨饼name
的总订单quantity
。The 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 }
}
] )
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
阶段。
Groups the documents by date using使用$dateToString
.$dateToString
按日期对文档进行分组。For each group, calculates:对于每组,计算:Passes the grouped documents to 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:某些聚合管道阶段接受聚合表达式,该表达式:
Specifies the transformation to apply to the current stage's input documents.指定要应用于当前阶段的输入文档的转换。Transform the documents in memory.转换内存中的文档。Can specify aggregation expression operators to calculate values.可以指定聚合表达式运算符来计算值。Can contain additional nested aggregation expressions.可以包含其他嵌套聚合表达式。
Starting in MongoDB 4.4, you can use the 从MongoDB 4.4开始,您可以使用$accumulator
and $function
aggregation operators to define custom aggregation expressions in JavaScript.$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:要使用聚合管道更新文档,请使用:
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-reduce。Aggregation pipelines provide better performance and usability than 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对于需要自定义功能的map-reduce操作,可以使用$accumulator
and$function
aggregation operators, available starting in version 4.4.$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:有关映射减少的聚合管道替代方案的示例,请参阅:
Learn More了解更多信息
To learn more about aggregation pipelines, see:要了解有关聚合管道的更多信息,请参阅: