定义
aggregate使用 聚合管道执行聚合操作。管道可以让您通过一系列阶段处理来自集合或其他来源的数据。
提示
In
mongosh, this command can also be run through thedb.aggregate()anddb.collection.aggregate()helper methods or with thewatch()helper method.Helper methods are convenient for
mongoshusers, but they may not return the same level of information as database commands. In cases where the convenience is not needed or the additional return fields are required, use the database command.
兼容性
此命令可用于以下环境中托管的部署:
- MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
重要
This command has limited support in M0 and Flex clusters. For more information, see Unsupported Commands.
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
在版本5.0中进行了更改。
该命令具有以下语法:
db.runCommand( { aggregate: "<collection>" || 1, pipeline: [ <stage>, <...> ], explain: <boolean>, allowDiskUse: <boolean>, allowPartialResults: <boolean>, cursor: <document>, maxTimeMS: <int>, bypassDocumentValidation: <boolean>, readConcern: <document>, collation: <document>, hint: <string or document>, comment: <any>, writeConcern: <document>, let: <document>, // Added in MongoDB 5.0 querySettings: <document> // Added in MongoDB 9.0 } )
命令字段
The aggregate command takes the following fields as arguments:
字段 | 类型 | 说明 | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 字符串 | 充当聚合管道的输入的集合或视图的名称。使用 | ||||||||||
| 阵列 | 聚合管道阶段数组,作为聚合管道的一部分处理和转换文档流。 | ||||||||||
| 布尔 | 可选。指定返回关于管道处理的信息。 不适用于多文档事务。 | ||||||||||
| 布尔 | 可选。 使用此选项可以覆盖特定查询的
从 MongoDB 6.0 开始,如果 有关详细信息,请参阅 | ||||||||||
| 布尔 | 可选。对于通过 Set Since a shard can become unavailable at any point, partial results can appear in the initial 如果管道满足以下条件,该命令将返回
| ||||||||||
| 文档 | 指定包含控制游标对象创建选项的文档。 You must use the
| ||||||||||
| non-negative integer | 可选。 指定时间限制(以毫秒为单位)。如果您未指定 MongoDB 使用与 | ||||||||||
| 布尔 | |||||||||||
| 文档 | 可选。指定读关注。
可能的读关注级别是:
有关读关注级别的更多信息,请参阅读关注级别。
| ||||||||||
| 文档 | 可选。 可选。指定用于操作的排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 排序规则选项的语法如下: 指定排序规则时, 如果未指定排序规则,但集合具有默认排序规则(请参阅 如果没有为收集或操作指定排序规则,MongoDB 将使用先前版本中使用的简单二进制比较来进行字符串比较。 您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。 | ||||||||||
| 字符串或文档 | |||||||||||
| any | 可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:
注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。 在 | ||||||||||
| 文档 | |||||||||||
| 文档 | 可选。 指定包含变量列表的文档。这样可以将变量与查询文本分开,从而提高命令的可读性。 文档语法为: 变量设置为表达式返回的值,并且之后不能再进行更改。 要访问命令中的变量值,请使用双美元符号前缀 ( 要使用变量筛选管道 For a complete example using 版本 5.0 中的新增功能。 | ||||||||||
| 文档 | 可选。仅应用于此命令执行的查询设置。
有关这些字段的说明,请参阅 命令字段。 MongoDB 不会在集群上存储这些设置,这些设置也不应用于具有相同 查询结构 的其他查询。要为查询结构设置持久有效的查询设置,请使用 MongoDB 会将您在命令中传递的设置与集群上为同一查询结构存储的任何查询设置相结合。如果两个设置指定了同一个字段,则以存储的集群设置为准。 9.0版本新增。 |
You must use the aggregate command with the cursor option unless the command includes the explain option.
要指示具有默认批次大小的游标,请指定
cursor: {}。要指示具有非默认批次大小的游标,请使用
cursor: { batchSize: <num> }。
有关聚合管道的更多信息,请参阅:
会话
对于在一个会话内创建的游标,不能在该会话外调用 getMore。
同样,对于在会话外创建的游标,不能在会话内调用 getMore。
会话空闲超时
MongoDB drivers and mongosh associate all operations with a server session, with the exception of unacknowledged write operations. For operations not explicitly associated with a session (i.e. using Mongo.startSession()), MongoDB drivers and mongosh create an implicit session and associate it with the operation.
如果会话空闲时间超过 30 分钟,MongoDB Server 会将该会话标记为已过期,并可能随时将其关闭。当 MongoDB Server 关闭会话时,它还会终止任何正在进行的操作并打开与会话关联的游标。这包括使用超过 30 分钟的 noCursorTimeout() 或 maxTimeMS() 配置的游标。
如果游标可能空闲超过 30 分钟,请使用 Mongo.startSession() 在显式会话中发出操作。使用 refreshSessions 命令定期刷新会话。有关详细信息,请参阅会话空闲超时。
事务
aggregate can be used inside distributed transactions.
但是,事务中不允许有以下阶段:
此外,您不能指定 explain 选项。
重要
在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。
有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项。
客户端断开连接
For aggregate operations that do not include the $out or $merge stages:
If the client that issued aggregate disconnects before the operation completes, MongoDB marks aggregate for termination using killOp.
查询设置
8.0版本新增。
您可以使用查询设置来设置索引提示、设置操作拒绝过滤器以及其他字段。这些设置将应用于整个集群上的查询结构。在关闭之后,集群将保留这些设置。
在查询规划期间,查询优化器将使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。您还可以使用查询设置来阻塞查询结构。
要添加查询设置并探索示例,请参阅 setQuerySettings。
You can add query settings for find, distinct, and aggregate commands.
查询设置具有更多功能,相比已弃用的索引过滤器而言是您的首选。
要删除查询设置,请使用 removeQuerySettings。要获取查询设置,请在一个聚合管道中使用一个 $querySettings 阶段。
Stable API
When using Stable API V1, the aggregate command is supported with the following exceptions:
Stable API V1 中不提供以下聚合阶段:
Stable API V1 中没有
explain字段。如果包含该字段,服务器将返回 APIStrictError 错误。使用
$collStats阶段时,只有count字段可用。Stable API V1 中没有其他可用的$collStats字段。
例子
You must use the aggregate command with the cursor option unless the command includes the explain option.
要指示具有默认批次大小的游标,请指定
cursor: {}。要指示具有非默认批次大小的游标,请使用
cursor: { batchSize: <num> }。
Instead of running the aggregate command directly, use the db.collection.aggregate() helper in mongosh or the equal helper in your driver.
除演示命令语法的前两个示例外,本页中的示例均使用 db.collection.aggregate() 辅助工具/辅助程序。
本页上的示例使用来自 sample_mflix 数据集的数据。有关如何将此数据集加载到您的自管理 MongoDB 部署中的详细信息,请参阅 加载示例数据集。如果您对示例数据库进行了任何修改,您可能需要删除并重新创建数据库,才能运行此页面上的示例。
使用多阶段管道聚合数据
sample_mflix数据库中的 movies集合包含如下document:
注意
movies集合中的document包含此处未显示的其他字段。
{ title: 'The Shawshank Redemption', year: 1994, genres: [ 'Crime', 'Drama' ], runtime: 142, imdb: { rating: 9.3, votes: 1521105, id: 111161 }, directors: [ 'Frank Darabont' ], cast: [ 'Tim Robbins', 'Morgan Freeman', 'Bob Gunton', 'William Sadler' ], }, { title: 'The Godfather', year: 1972, genres: [ 'Crime', 'Drama' ], runtime: 175, imdb: { rating: 9.2, votes: 1038358, id: 68646 }, directors: [ 'Francis Ford Coppola' ], cast: [ 'Marlon Brando', 'Al Pacino', 'James Caan', 'Richard S. Castellano' ] }, { title: 'Pulp Fiction', year: 1994, genres: [ 'Crime', 'Drama' ], runtime: 154, imdb: { rating: 8.9, votes: 1179033, id: 110912 }, directors: [ 'Quentin Tarantino' ], cast: [ 'Tim Roth', 'Amanda Plummer', 'Laura Lovelace', 'John Travolta' ] }, { title: 'Forrest Gump', year: 1994, genres: [ 'Drama', 'Romance' ], runtime: 142, imdb: { rating: 8.8, votes: 1087227, id: 109830 }, directors: [ 'Robert Zemeckis' ], cast: [ 'Tom Hanks', 'Rebecca Williams', 'Sally Field', 'Michael Conner Humphreys' ], }, { title: 'Inception', year: 2010, genres: [ 'Action', 'Sci-Fi', 'Thriller' ], runtime: 148, imdb: { rating: 8.8, votes: 1294646, id: 1375666 }, directors: [ 'Christopher Nolan' ], cast: [ 'Leonardo DiCaprio', 'Joseph Gordon-Levitt', 'Ellen Page', 'Tom Hardy' ], }
以下示例聚合 movies 集合以计算每个不同类型的数量:
db.runCommand( { aggregate: "movies", pipeline: [ { $project: { genres: 1 } }, { $unwind: "$genres" }, { $group: { _id: "$genres", count: { $sum : 1 } } } ], cursor: { } } )
In mongosh, run the same aggregation using the db.collection.aggregate() helper:
db.movies.aggregate( [ { $project: { genres: 1 } }, { $unwind: "$genres" }, { $group: { _id: "$genres", count: { $sum: 1 } } } ] )
在管理员数据库上使用 $currentOp
以下示例将在管理员数据库上运行两个阶段的管道。第一阶段执行 $currentOp 操作,第二阶段执行过滤器结果。
db.adminCommand( { aggregate : 1, pipeline : [ { $currentOp : { allUsers : true, idleConnections : true } }, { $match : { shard : "shard01" } } ], cursor : { } })
注意
The aggregate command does not specify a collection and instead takes the form {aggregate: 1}. The initial $currentOp stage does not draw input from a collection. The stage produces its own data for the rest of the pipeline to use.
db.aggregate() 辅助工具支持此类无集合聚合。运行上述聚合,如 此示例。
返回聚合操作信息
以下示例将 explain 设置为 true 以返回有关聚合的信息。
db.comments.aggregate( [ { $match: { date: { $gte: ISODate("2015-01-01") } } }, { $group: { _id: "$movie_id", commentCount: { $sum: 1 } } }, { $sort: { commentCount: -1 } } ], { explain: true } )
注意
解释输出可能因版本而异。
互动 allowDiskUseByDefault
默认下,需要超过 100 MB 内存才能执行的管道阶段会将临时文件写入磁盘。这些临时文件在管道执行期间持续存在,并且可能影响实例上的存储空间。
单个 find 和 aggregate 命令可以通过以下任一方式覆盖 allowDiskUseByDefault 参数:
使用
{ allowDiskUse: true }以允许在allowDiskUseByDefault设置为false时将临时文件写入磁盘使用
{ allowDiskUse: false }以禁止在allowDiskUseByDefault设置为true时将临时文件写入磁盘
指定批处理大小的聚合数据
要设置初始批处理大小,请在 cursor 字段中包含 batchSize:
db.theaters.aggregate( [ { $match: { "location.address.state": "NY" } }, { $group: { _id: "$location.address.city", theaterCount: { $sum: 1 } } }, { $sort: { theaterCount: -1 } }, { $limit: 2 } ], { cursor: { batchSize: 0 } } )
{ cursor: { batchSize: 0 } } 文档指定初始批处理大小,并表示首次批处理为空。这可以快速返回游标或失败消息,无需执行大量服务器端工作。
要为后续 getMore 操作指定批处理大小,请在 mongosh 中使用 batchSize(),或在 getMore 命令中使用 batchSize 字段。
指定排序规则
排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。
以下聚合操作返回 sample_mflix数据库的 movies集合中所有法国电影的标题,并指定 fr 排序规则:
db.movies.aggregate( [ { $match: {"countries": "France", "languages": "French"} }, { $project: { "title": 1, "_id": 0 } } ], { collation: { locale: "fr", strength: 1 } } )
有关排序规则字段的说明,请参阅排序规则文档。
提示索引
sample_mflix数据库中的 movies集合包含与以下类似的document:
{ title: "The Shawshank Redemption", year: 1994, rated: "R", imdb: { rating: 9.3, votes: 1513145, id: 111161 } }, { title: "The Godfather", year: 1972, rated: "R", imdb: { rating: 9.2, votes: 1038358, id: 68646 } }, { title: "The Dark Knight", year: 2008, rated: "PG-13", imdb: { rating: 9, votes: 1495351, id: 468569 } }, { title: "Forrest Gump", year: 1994, rated: "PG-13", imdb: { rating: 8.8, votes: 1087227, id: 109830 } }
假设 movies集合上存在以下索引:
db.movies.createIndex( { "imdb.rating": 1, year: 1 } )
db.movies.createIndex( { "imdb.rating": 1, rated: 1 } )
下面的聚合操作包含 hint 选项,强制使用指定的索引:
db.movies.aggregate( [ { $sort: { "imdb.rating": 1 } }, { $match: { rated: "R", "imdb.rating": { $gte: 9.0 } } }, { $sort: { year: -1 } } ], { hint: { "imdb.rating": 1, rated: 1 } } )
覆盖默认读关注
To override the default read concern level, use the readConcern option. The getMore command uses the readConcern level specified in the originating aggregate command.
movies对sample_mflix 数据库中的 集合的以下操作指定了 读关注(read concern) 的 "majority" ,以读取已确认已写入大多数节点的数据的最新副本。
重要
您可以为包含
$out阶段的聚合指定读关注级别"majority"。无论读关注级别如何,节点上的最新数据可能无法反映系统中数据的最新版本。
db.movies.aggregate( [ { $match: { "imdb.rating": { $gte: 8.0 } } }, { $group: { _id: "$rated", avgRating: { $avg: "$imdb.rating" }, count: { $sum: 1 } } }, { $sort: { avgRating: -1 } } ], { readConcern: { level: "majority" } } )
为确保单个线程可以读取自己的写入内容,请对副本集的主节点使用 "majority" 读关注和 "majority" 写关注。
使用以下项中的变量: let
要定义可在命令中其他位置访问的变量,请使用let选项。
sample_mflix数据库中的 movies集合包含如下document:
{ title: "The Shawshank Redemption", year: 1994, rated: "R", imdb: { rating: 9.3, votes: 1513145, id: 111161 }, runtime: 142 }
以下示例使用 let 选项为管道定义变量。该示例查找评分高且运行时间长的电影:
db.runCommand( { aggregate: "movies", pipeline: [ { $match: { $expr: { $and: [ { $gte: [ "$imdb.rating", "$$minRating" ] }, { $gte: [ "$runtime", "$$minRuntime" ] } ] } } }, { $project: { title: 1, year: 1, "imdb.rating": 1, runtime: 1 } }, { $sort: { "imdb.rating": -1 } }, { $limit: 3 } ], cursor: {}, let: { minRating: 8.5, minRuntime: 120 } } )