对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

聚合(数据库命令)

aggregate

使用 聚合管道执行聚合操作。管道可以让您通过一系列阶段处理来自集合或其他来源的数据。

提示

In mongosh, this command can also be run through the db.aggregate() and db.collection.aggregate() helper methods or with the watch() helper method.

Helper methods are convenient for mongosh users, 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.

在版本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:

字段
类型
说明

aggregate

字符串

充当聚合管道的输入的集合或视图的名称。使用 1 执行与集合无关的命令。

pipeline

阵列

聚合管道阶段数组,作为聚合管道的一部分处理和转换文档流。

explain

布尔

可选。指定返回关于管道处理的信息。

不适用于多文档事务。

allowDiskUse

布尔

可选。

使用此选项可以覆盖特定查询的 allowDiskUseByDefault。您可以使用此选项执行以下任一操作:

  • 禁止在默认允许使用磁盘的系统上使用磁盘。

  • 支持在默认情况下禁止使用磁盘的系统上使用磁盘。

从 MongoDB 6.0 开始,如果 allowDiskUseByDefault 设置为 true,并且服务器需要超过 100 MB 的内存用于管道执行阶段,那么 MongoDB 会自动将临时文件写入磁盘,除非查询指定了 { allowDiskUse: false }。

有关详细信息,请参阅allowDiskUseByDefault。

如果聚合阶段因为内存限制而写入临时文件,则分析器日志消息和诊断日志消息包含一个 usedDisk 指示器。

allowPartialResults

布尔

可选。对于通过 mongos 针对分片集合运行的聚合,当一个或多个查询的分片不可用时,该命令可以返回部分结果,而不是错误。后续 getMore 命令也可以返回部分结果。默认为 false,如果查询的分片不可用,则返回错误。

Set allowPartialResults on the initial aggregate command only. You cannot set it on getMore, but each getMore inherits the setting from the cursor.

Since a shard can become unavailable at any point, partial results can appear in the initial aggregate response, in a later getMore response, or both. When a batch omits results from unavailable shards, that batch's response includes a partialResultsReturned: true field. When all queried shards are available for a batch, the response omits partialResultsReturned. partialResultsReturned can contain only documents from available shards. Do not assume the result set is complete when partialResultsReturned is true.

如果管道满足以下条件,该命令将返回 InvalidOptions 错误:

  • 以写入阶段结束,例如 $out 或 $merge。

  • 是一个 变更流 聚合。

  • 包含一个 Atlas Search 阶段,例如 $search、$vectorSearch、$rankFusion 或 $scoreFusion。

cursor

文档

指定包含控制游标对象创建选项的文档。

You must use the aggregate command with the cursor option unless the command includes the explain option.

  • 要指示具有默认批次大小的游标,请指定 cursor: {}。

  • 要指示具有非默认批次大小的游标,请使用 cursor: { batchSize: <num> }。

maxTimeMS

non-negative integer

可选。

指定时间限制(以毫秒为单位)。如果您未指定 maxTimeMS 值,操作将不会超时。如果值为 0 ,则显式指定默认无限制行为。

MongoDB 使用与 db.killOp() 相同的机制终止超过分配的时间限制的操作。MongoDB 仅在指定的中断点之一中终止操作。

bypassDocumentValidation

布尔

可选。仅当您指定 $out 或 $merge 聚合阶段时使用。

启用 aggregate 可在此操作过程中绕过模式验证。 这使您能够插入不符合验证要求的文档。

readConcern

文档

可选。指定读关注。

readConcern 选项的语法如下:readConcern: { level: <value> }

可能的读关注级别是:

有关读关注级别的更多信息,请参阅读关注级别。

$out 阶段不能与读关注 "linearizable" 一起使用。如果为 db.collection.aggregate() 指定 "linearizable" 读关注,则不能将 $out 阶段包括在管道中。

$merge 阶段不能与读关注 "linearizable" 一起使用。换言之,如果您为 db.collection.aggregate() 指定 "linearizable" 读关注,则不能将 $merge 阶段包括在管道中。

collation

文档

可选。

可选。指定用于操作的排序规则。

排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。

排序规则选项的语法如下:

collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}

指定排序规则时,locale 字段为必填字段;所有其他排序规则字段均为可选字段。有关字段的说明,请参阅排序规则文档。

如果未指定排序规则,但集合具有默认排序规则(请参阅 db.createCollection()),则操作将使用为集合指定的排序规则。

如果没有为收集或操作指定排序规则,MongoDB 将使用先前版本中使用的简单二进制比较来进行字符串比较。

您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果执行带排序的查找,则不能使用一种排序规则进行查找而另一种排序规则进行排序。

hint

字符串或文档

可选.用于该聚合的索引。该索引位于运行聚合的初始集合或视图上。

通过索引名称或索引规范文档来指定索引。

hint 不适用于 $lookup 和 $graphLookup 阶段。

comment

any

可选。用户提供的待附加到该命令的注释。设置后,该注释将与该命令的记录一起出现在以下位置:

注释可以是任何有效的 BSON 类型(字符串、整型、对象、数组等)。

在 aggregate 命令上设置的任何注释都将由在 aggregate 游标上运行的任何后续 getMore 命令继承。

writeConcern

文档

可选。一个表达写关注的文档,该写关注会与 $out 或 $merge 阶段一起配合使用。

在 $out 或 $merge 阶段省略使用默认写关注。

let

文档

可选。

指定包含变量列表的文档。这样可以将变量与查询文本分开,从而提高命令的可读性。

文档语法为:

{
<variable_name_1>: <expression_1>,
...,
<variable_name_n>: <expression_n>
}

变量设置为表达式返回的值,并且之后不能再进行更改。

要访问命令中的变量值,请使用双美元符号前缀 ($$) 以及 $$<variable_name> 形式的变量名称。例如:$$targetTotal。

要使用变量筛选管道 $match 阶段的结果,必须在 $expr 运算符中访问该变量。

For a complete example using let and variables, see Use Variables in let.

版本 5.0 中的新增功能。

querySettings

文档

可选。仅应用于此命令执行的查询设置。querySettings 文档接受以下字段:

  • indexHints

  • queryFramework

  • reject

  • comment

  • queryKnobs

  • maxTimeMS

有关这些字段的说明,请参阅 命令字段。

MongoDB 不会在集群上存储这些设置,这些设置也不应用于具有相同 查询结构 的其他查询。要为查询结构设置持久有效的查询设置,请使用 setQuerySettings。

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 选项。

  • 对于在 ACID 事务外部创建的游标,无法在 ACID 事务内部调用 getMore。

  • 对于在事务中创建的游标,无法在事务外部调用 getMore。

重要

在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。

有关其他事务使用注意事项(如运行时间限制和 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 阶段。

When using Stable API V1, the aggregate command is supported with the following exceptions:

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 操作,第二阶段执行过滤器结果。

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

注意

解释输出可能因版本而异。

默认下,需要超过 100 MB 内存才能执行的管道阶段会将临时文件写入磁盘。这些临时文件在管道执行期间持续存在,并且可能影响实例上的存储空间。

单个 find 和 aggregate 命令可以通过以下任一方式覆盖 allowDiskUseByDefault 参数:

  • 使用 { allowDiskUse: true } 以允许在 allowDiskUseByDefault 设置为 false 时将临时文件写入磁盘

  • 使用 { allowDiskUse: false } 以禁止在 allowDiskUseByDefault 设置为 true 时将临时文件写入磁盘

如果聚合阶段因为内存限制而写入临时文件,则分析器日志消息和诊断日志消息包含一个 usedDisk 指示器。

要设置初始批处理大小,请在 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选项。

注意

要通过在管道 $match 阶段使用变量筛选结果,必须访问 $expr 运算符中的变量。

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