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

db. 集合.aggregate()(mongosh方法)

带驱动程序的 MongoDB

此页面记录了mongosh方法。要查看MongoDB驾驶员中的等效方法,请参阅您的编程语言的相应页面:
db.collection.aggregate(pipeline, options)

计算集合或视图中数据的聚合值。

返回:
  • 在聚合分析管道的最后阶段生成的文档游标。

  • 如果管道包含 explain 选项,查询将返回一个详细说明聚合操作处理的文档。

  • 如果管道包含 $out 或 $merge 操作符,查询将返回一个空游标。

可以使用 db.collection.aggregate() 查找托管在以下环境中的部署:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

db.collection.aggregate() 采用以下形式:

db.collection.aggregate( <pipeline>, <options> )

db.collection.aggregate() 使用以下参数:

Parameter
类型
说明

pipeline

阵列

一系列数据聚合操作或阶段。 See the aggregation pipeline operators for details.

该方法仍然可以接受管道阶段作为单独的参数,而不是作为数组中的元素;但是,如果您未将 pipeline 指定为数组,则无法指定 options 参数。

options

文档

可选。 传递给aggregate() aggregate命令的其他选项。仅当您将pipeline 指定为大量时才可用。要查看可用选项,请参阅 AggregateOptions。

如果发生错误,aggregate() 助手会抛出异常。

在mongosh 中,如果未使用aggregate() var关键字将 游标分配给变量,则mongosh 会自动迭代游标,最多20 次。有关在 中处理游标的信息,请参阅在mongosh中迭代游标。mongosh

聚合返回的游标只支持对已评估游标进行操作的游标方法(即第一批已检索到的游标),如以下方法:

有关更多信息,请参阅:

对于在一个会话内创建的游标,不能在该会话外调用 getMore。

同样,对于在会话外创建的游标,不能在会话内调用 getMore。

MongoDB驱动程序和mongosh 将所有操作与服务器会话关联,但未确认的写入操作除外。对于未显式与会话关联的操作(即使用 ),Mongo.startSession() MongoDB驱动程序和mongosh 会创建一个隐式会话并将其与操作关联。

如果会话空闲时间超过 30 分钟,MongoDB Server 会将该会话标记为已过期,并可能随时将其关闭。当 MongoDB Server 关闭会话时,它还会终止任何正在进行的操作并打开与会话关联的游标。这包括使用超过 30 分钟的 noCursorTimeout() 或 maxTimeMS() 配置的游标。

对于返回游标的操作,如果游标的空闲时间可能超过 30 分钟,则使用 Mongo.startSession() 在显式会话中发出操作,并使用 refreshSessions 命令定期刷新会话。更多信息,请参阅会话空闲超时。

aggregate() 可用于分布式事务。

但是,事务中不允许有以下阶段:

此外,您不能指定 explain 选项。

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

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

重要

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

有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项。

对于不包含 $out 或 $merge 阶段的 aggregate() 操作:

如果发出 aggregate() 的客户端在操作完成之前断开连接,则MongoDB使用killOp将 aggregate() 标记为终止。

8.0版本新增。

您可以使用查询设置来设置索引提示、设置操作拒绝过滤器以及其他字段。这些设置将应用于整个集群上的查询结构。在关闭之后,集群将保留这些设置。

在查询规划期间,查询优化器将使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。您还可以使用查询设置来阻塞查询结构。

要添加查询设置并探索示例,请参阅 setQuerySettings。

您可以为 find、distinct 和 aggregate 命令添加查询设置。

查询设置具有更多功能,相比已弃用的索引过滤器而言是您的首选。

要删除查询设置,请使用 removeQuerySettings。要获取查询设置,请在一个聚合管道中使用一个 $querySettings 阶段。

本页上的示例使用sample_mflix示例数据集中的数据。有关如何将此数据集加载到自管理MongoDB 部署中的详细信息,请参阅加载示例数据集。如果对示例数据库进行了任何修改,则可能需要删除并重新创建数据库才能运行本页上的示例。

注意

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' ],
}

以下聚合操作:

  • 选择 IMDB 评级大于 8.5 的电影

  • 按 year字段对匹配的电影进行分组

  • 根据 imdb.rating字段的平均值计算每个 year 的 averageRating

  • 按 averageRating字段降序对结果进行排序

db.movies.aggregate(
[
{ $match: { "imdb.rating": { $gt: 8.5 } } },
{ $group: { _id: "$year", averageRating: { $avg: "$imdb.rating" } } },
{ $sort: { averageRating: -1 } },
{ $limit: 3 }
]
)

该操作返回一个包含以下文档的游标:

[
{ _id: 1972, averageRating: 9.2 },
{ _id: 1990, averageRating: 9.166666666666666 },
{ _id: 1974, averageRating: 9.1 }
]

mongosh自动遍历返回的游标以打印结果。有关在 中手动处理游标的信息,请参阅在mongosh中迭代游标。mongosh

以下示例使用 db.collection.explain() 查看聚合管道执行计划的详细信息。

db.movies.explain().aggregate(
[
{ $match: { "imdb.rating": { $gt: 8.5 } } },
{ $group: { _id: "$year", averageRating: { $avg: "$imdb.rating" } } },
{ $sort: { averageRating: -1 } }
]
)

该操作返回一个文档,其中详细说明了聚合管道的处理。 示例,除其他详细信息外,文档还可以显示该操作使用的索引(如果有)。 [ 1 ]如果movies集合是分分片的集合,则文档还会显示分片和合并操作之间的分工,以及针对定向查询的目标分片。

注意

explain 输出文档的目标读者是人类,而不是机器,并且输出格式因版本而不同。

您可以将 executionStats 或 allPlansExecution 解释模式传递给 db.collection.explain() 方法,以查看更详细的解释输出。

[1] 索引筛选器可能影响所用索引的选择。详情参见索引筛选器。

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

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

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

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

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

有关更多信息,请参阅聚合管道限制。

要指定游标的初始批次大小,请对 cursor 选项使用以下语法:

cursor: { batchSize: <int> }

例如,以下聚合操作指定游标的初始批处理大小为 0:

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字段。

mongosh自动遍历返回的游标以打印结果。有关在 中手动处理游标的信息,请参阅在mongosh中迭代游标。mongosh

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

以下聚合操作返回 sample_mflix数据库的 movies集合中所有法国电影的标题,并指定 fr 排序规则:

db.movies.aggregate(
[
{ $match: {"countries": "France", "languages": "French"} },
{ $project: { "title": 1, "_id": 0 } }
],
{ collation: { locale: "fr", strength: 1 } }
)

注意

如果执行的聚合涉及多个视图,例如使用 $lookup 或 $graphLookup ,则这些视图必须采用相同的排序规则。

有关排序规则字段的说明,请参阅排序规则文档。

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

若要覆盖默认的读关注级别,请使用 readConcern 选项。getMore 命令使用原始 aggregate 命令中指定的 readConcern 级别。

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" 写关注。

sample_mflix示例数据集中的 movies集合包含与此类似的document:

{
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' ],
}

以下聚合操作查找在 1994 中创建的电影,并包含 comment 选项,以在 logs、db.system.profile集合和 db.currentOp 中提供跟踪信息。

db.movies.aggregate(
[
{ $match: { year : 1994 } },
{ $limit: 3 }
],
{ comment: "match_three_movies_from_1994" }
)

在启用了分析的系统上,您可以查询 system.profile 集合以查看所有最近的类似聚合,如下所示:

db.system.profile.find( { "command.aggregate": "movies", "command.comment" : "match_three_movies_from_1994" } ).sort( { ts : -1 } ).pretty()

这将以下列格式返回一组剖析器结果:

{
"op" : "command",
"ns" : "video.movies",
"command" : {
"aggregate" : "movies",
"pipeline" : [
{
"$match" : {
"year" : 1994
}
},
{ "$limit": 3 }
],
"comment" : "match_three_movies_from_1994",
"cursor" : {
},
"$db" : "video"
},
...
}

应用程序可以对注释中的任意信息进行编码,以便更轻松地跟踪或识别整个系统的特定操作。例如,应用程序可能会附加一个字符串注释,其中包含其进程 ID、线程 ID、客户端主机名和发出命令的用户。

要定义可在命令中其他位置访问的变量,请使用let选项。

注意

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

如下示例:

  • 匹配 sample_mflix.movies集合中 imdb.rating字段大于 8.5 的document,最多三个结果

  • 在 let 中定义了一个 minRating 变量,该变量在 $gt 中被引用为 $$minRating

db.movies.aggregate(
[
{ $match: {
$expr: { $gt: [ "$imdb.rating", "$$minRating" ] }
} },
{ $limit: 3 }
],
{ let: { minRating: 8.5 } }
)
给本页内容打分