# 聚合管道

在本页面

* [管道](#pipeline)
* [管道表达式](#pipeline-expressions)
* [聚合管道行为](#aggregation-pipeline-behavior)
* [注意事项](#considerations)

聚合管道是用于数据聚合的框架，其模型基于数据处理管道的概念。文档进入多阶段管道，将文档转换为聚合结果。例如：

在这个例子中

```
db.orders.aggregate([
    { $match: { status: "A" } },
    { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
```

**第一阶段**：[`$match`](/aggregation/aggregation-pipeline.md)阶段按`status`字段过滤文档，并将`status`等于`"A"`的文档传递到下一阶段。

**第二阶段**：[`$group`](/aggregation/aggregation-pipeline.md)阶段按`cust_id`字段将文档分组，以计算每个`cust_id`唯一值的金额总和。

## 管道

MongoDB 聚合管道由多个[阶段](/can-kao/yun-suan-fu/aggregation-pipeline-stages.md)组成。每个阶段在文档通过管道时转换文档。管道阶段不需要为每个输入文档生成一个输出文档; 如：某些阶段可能会生成新文档或过滤掉文档。

Pipeline阶段可以与外管道出现多次[`$out`](/aggregation/aggregation-pipeline.md)，[`$merge`](/aggregation/aggregation-pipeline.md)和 [`$geoNear`](/aggregation/aggregation-pipeline.md)阶段。有关所有可用阶段的列表，请参见 [聚合管道阶段](/aggregation/aggregation-pipeline.md)。

MongoDB 在[mongo](https://github.com/mongodb-china/MongoDB-CN-Manual/tree/8490376c81d56eff95abbaddc6ee414b1e1c9705/docs/docs/Reference/MongoDB-Package-Components/mongo.md) shell 中提供[db.collection.aggregate()](/can-kao/mongo-shell-methods/collection-methods/db-collection-aggregate.md)方法，在聚合管道中提供[聚合](https://github.com/mongodb-china/MongoDB-CN-Manual/tree/8490376c81d56eff95abbaddc6ee414b1e1c9705/docs/docs/Reference/Database-Commands/Aggregation-Commands.md)命令。

对于聚合管道的 example 用法，请考虑[使用用户首选项数据进行聚合](/aggregation/aggregation-pipeline/example-with-user-preference-data.md)和[使用 Zip Code 数据集进行聚合](/aggregation/aggregation-pipeline/example-with-zip-code-data.md)。

从MongoDB 4.2开始，您可以使用聚合管道在以下位置进行更新：

| 命令                                                      | Mongoshall方法                                                                                                                                                                                                                                                                                                                                                                            |
| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`findAndModify`](/aggregation/aggregation-pipeline.md) | [db.collection.findOneAndUpdate（）](/aggregation/aggregation-pipeline.md) [db.collection.findAndModify（）](/aggregation/aggregation-pipeline.md)                                                                                                                                                                                                                                          |
| [`pdate`](/aggregation/aggregation-pipeline.md)         | [db.collection.updateOne（）](/aggregation/aggregation-pipeline.md) [db.collection.updateMany（）](/aggregation/aggregation-pipeline.md) [db.collection.update（）](/aggregation/aggregation-pipeline.md) [Bulk.find.update（）](/aggregation/aggregation-pipeline.md) [Bulk.find.updateOne（）](/aggregation/aggregation-pipeline.md) [Bulk.find.upsert（）](/aggregation/aggregation-pipeline.md) |

> **\[success] 也可以看看**
>
> [聚合管道更新](/aggregation/aggregation-pipeline.md)

## 管道表达式

某些管道阶段将管道表达式作为操作数。管道表达式指定要应用于输入文档的转换。表达式具有[文档](https://github.com/mongodb-china/MongoDB-CN-Manual/tree/8490376c81d56eff95abbaddc6ee414b1e1c9705/docs/Introduction-to-MongoDB/Documents.md)结构，可以包含其他[表达式](/aggregation/aggregation-reference/aggregation-pipeline-quick-reference.md)。

管道表达式只能对管道中的当前文档进行操作，并且不能引用其他文档中的数据：表达式操作提供文档的内存转换。

通常，表达式是无状态的，只有在聚合过程看到表达式时才计算，只有一个例外：[累加器](/aggregation/aggregation-reference/aggregation-pipeline-quick-reference.md)表达式。

在[$group](/aggregation/aggregation-pipeline.md)阶段中使用的累加器在记录管道中的进程时维护它们的状态(如： 总计，最大值，最小值和相关数据)。

Mongodb 3.2的变化：[$project](/aggregation/aggregation-pipeline.md)阶段有一些累加器可用;但是，在[$project](/aggregation/aggregation-pipeline.md)阶段使用时，累加器不会跨文档维护它们的状态。

有关表达式的更多信息，请参阅[表达式](/aggregation/aggregation-reference/aggregation-pipeline-quick-reference.md)。

## 聚合管道行为

在 MongoDB 中，[管道](/aggregation/aggregation-pipeline.md)命令在单个集合上运行，从逻辑上将整个集合传递到聚合管道。为了尽可能优化操作，请使用以下策略以避免扫描整个集合。

### 管道运算符和索引

MongoDB的[query planner](/aggregation/aggregation-pipeline.md)分析聚合管道，以确定是否可以使用[索引](https://docs.mongodb.com/manual/indexes/#indexes)来改善管道性能。例如，以下管道阶段可以利用索引：

> **\[success] 注意**
>
> 以下管道阶段并不代表可以使用索引的所有阶段的完整列表。

* **$match**

  如果[`$match`](/aggregation/aggregation-pipeline.md)阶段出现在管道的开始，该阶段可以使用索引来过滤文档。
* **$sort**

  只要前面没有[`$project`](/aggregation/aggregation-pipeline.md)，[`$unwind`](/aggregation/aggregation-pipeline.md)或 [`$group`](/aggregation/aggregation-pipeline.md)阶段，[`$sort`](/aggregation/aggregation-pipeline.md)阶段可以使用索引。
* **$group**

  如果满足下列所有的条件，[`$group`](/aggregation/aggregation-pipeline.md)阶段有时可以使用的索引来查找每一个组中的第一文档：

  * [`$group`](/aggregation/aggregation-pipeline.md)阶段之前是一个[`$sort`](/aggregation/aggregation-pipeline.md) 阶段，该阶段对字段进行分组
  * 在分组的字段上有一个索引，它与排序顺序匹配
  * [`$group`](/aggregation/aggregation-pipeline.md)阶段中使用的唯一累加器是 [`$first`](/aggregation/aggregation-pipeline.md)

  有关示例，请参见[优化以返回每个组的第一个文档](/aggregation/aggregation-pipeline.md)。
* **$geoNear**

  [`$geoNear`](/aggregation/aggregation-pipeline.md)管道运算符利用地理空间索引。在使用时[`$geoNear`](/aggregation/aggregation-pipeline.md)， [`$geoNear`](/aggregation/aggregation-pipeline.md)管道操作必须出现在聚合管道的第一阶段出现。

> Mongodb 3.2 版本的改变：从MongoDB 3.2开始，索引可以覆盖聚合管道。在MongoDB 2.6和3.0中，索引无法覆盖聚合管道，因为即使管道使用索引，聚合仍需要访问实际文档。

### 早期过滤

如果聚合操作仅需要集合中的数据子集，请使用[$match](/aggregation/aggregation-pipeline.md)，[$limit](/aggregation/aggregation-pipeline.md)和[$skip](/aggregation/aggregation-pipeline.md)阶段来限制在管道开头输入的文档。当放置在管道的开头时，[$match](/aggregation/aggregation-pipeline.md)操作使用合适的索引来仅扫描集合中的匹配文档。

在管道的开头放置[$match](https://github.com/mongodb-china/MongoDB-CN-Manual/tree/8490376c81d56eff95abbaddc6ee414b1e1c9705/docs/Aggregation/reference-operator-aggregation-match.html#pipe._S_match)管道阶段后跟[$sort](https://github.com/mongodb-china/MongoDB-CN-Manual/tree/8490376c81d56eff95abbaddc6ee414b1e1c9705/docs/Aggregation/reference-operator-aggregation-sort.html#pipe._S_sort)阶段在逻辑上等同于具有排序的单个查询并且可以使用索引。如果可能，将[$match](https://github.com/mongodb-china/MongoDB-CN-Manual/tree/8490376c81d56eff95abbaddc6ee414b1e1c9705/docs/Aggregation/reference-operator-aggregation-match.html#pipe._S_match) 操作符放在管道的开头。

### 附加功能

聚合管道具有内部优化阶段，为 operators 的某些序列提供改进的 performance。有关详细信息，请参阅[聚合管道优化](/aggregation/aggregation-pipeline/aggregation-pipeline-optimization.md)。

聚合管道支持对分片集合的操作。见[聚合管道和分片集合](/aggregation/aggregation-pipeline/aggregation-pipeline-and-sharded-collections.md)。

* [聚合管道优化](/aggregation/aggregation-pipeline/aggregation-pipeline-optimization.md)
* [聚合管道限制](/aggregation/aggregation-pipeline/aggregation-pipeline-limits.md)
* [聚合管道和分片集合](/aggregation/aggregation-pipeline/aggregation-pipeline-and-sharded-collections.md)
* [使用 Zip Code 数据集进行聚合](/aggregation/aggregation-pipeline/example-with-zip-code-data.md)
* [Example with User Preference Data](/aggregation/aggregation-pipeline/example-with-user-preference-data.md)

## 注意事项

### 分片集合

聚合管道支持对分片集合的操作。请参阅[聚合管道和分片集合](/aggregation/aggregation-pipeline/aggregation-pipeline-and-sharded-collections.md)。

### 聚合管道与Map-Reduce的比较

聚合管道为[map-reduce](/aggregation/aggregation-pipeline.md)提供了一种替代方案，并且对于map-reduce的复杂性可能没有保障的聚合任务，它可能是首选的解决方案。

### 限制

聚合管道对值类型和结果大小有一些限制。有关聚合管道的限制和限制的详细信息，请参见[聚合管道限制](/aggregation/aggregation-pipeline/aggregation-pipeline-limits.md)。

### 管道优化

管道优化聚合管道具有内部优化阶段，可为某些操作符序列提供改进的性能。有关详细信息，请参阅[聚合管道优化](/aggregation/aggregation-pipeline/aggregation-pipeline-optimization.md)。

译者：李冠飞 刘翔

校对：李冠飞


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mongoing.com/aggregation/aggregation-pipeline.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
