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

聚合操作

在本指南中,您可以学习;了解如何使用 Mongoid 执行聚合操作。

聚合操作处理 MongoDB 集合中的数据并返回计算结果。 MongoDB 聚合框架是 Query API 的一部分,以数据处理管道的概念为模型。 文档进入包含一个或多个阶段的管道,该管道将文档转换为聚合结果。

聚合操作的功能类似于带有装配线的汽车工厂。 装配线设有配备专用工具的工位来执行特定任务。 例如,在制造汽车时,装配线从制造车架开始。 然后,当车架移动通过装配线时,每个工位都会组装一个单独的零件。 最终产品即成品汽车。

装配线代表聚合管道,各个工位代表聚合阶段,专用工具代表表达式操作符,而成品则代表聚合结果

下表列出了使用查找操作可以执行的不同任务,同时列出了使用聚合操作可以实现的任务作为对比。聚合框架提供了扩展功能,允许您转换和操作数据。

查找操作
聚合操作

选择要返回的特定文档
选择要返回的字段
对结果进行排序
限制结果
对结果进行计数

选择要返回的特定文档
选择要返回的字段
对结果进行排序
限制结果
计数结果
重命名字段
计算新字段
汇总数据
连接和合并数据集

您可以使用 Mongoid 的高级领域特定语言(DSL) 来构建聚合管道。 DSL 支持以下聚合管道操作符:

Operator
方法名称

group

project

unwind

要使用上述操作符之一创建聚合管道,请在 Criteria 的实例上调用相应的方法。 调用该方法会将聚合操作添加到 Criteria实例的 pipeline 属性中。 要运行聚合管道,请将 pipeline 属性值传递给 Collection#aggregate 方法。

考虑一个数据库,其中包含一个文档集合,这些文档由以下类建模:

class Tour
include Mongoid::Document
embeds_many :participants
field :name, type: String
field :states, type: Array
end
class Participant
include Mongoid::Document
embedded_in :tour
field :name, type: String
end

在此示例中,Tour 模型表示游览的名称及其途经的州,Participant 模型表示参加游览的人员的姓名。

以下示例创建了一个聚合管道,该管道使用以下聚合操作输出参与者访问过的状态:

  • match,用于查找 participants.name字段值为 "Serenity" 的文档

  • unwind,解构 states大量字段并输出大量中每个元素的文档

  • group,它会按文档的 states字段的值对文档进行分组

  • project,这会提示管道仅返回 _idstates 字段

criteria = Tour.where('participant.name' => 'Serenity').
unwind(:states).
group(_id: 'states', :states.add_to_set => '$states').
project(_id: 0, states: 1)
@states = Tour.collection.aggregate(criteria.pipeline).to_json
[{"states":["OR","WA","CA"]}]

您可以使用 Collection#aggregate 方法通过传入聚合操作大量来运行没有相应构建器方法的聚合操作。 使用此方法执行聚合会返回原始 BSON::Document 对象,而不是 Mongoid::Document 模型实例。

考虑一个数据库,其中包含一个文档集合,这些文档由以下类建模:

class Band
include Mongoid::Document
has_many :tours
has_many :awards
field :name, type: String
end
class Tour
include Mongoid::Document
belongs_to :band
field :year, type: Integer
end
class Award
include Mongoid::Document
belongs_to :band
field :name, type: String
end

以下示例创建了一个聚合管道,用于检索自 2000 以来进行过巡演且至少获得 1 个奖项的所有乐队:

band_ids = Band.collection.aggregate([
{ '$lookup' => {
from: 'tours',
localField: '_id',
foreignField: 'band_id',
as: 'tours',
} },
{ '$lookup' => {
from: 'awards',
localField: '_id',
foreignField: 'band_id',
as: 'awards',
} },
{ '$match' => {
'tours.year' => {'$gte' => 2000},
'awards._id' => {'$exists' => true},
} },
{'$project' => {_id: 1}},
])
bands = Band.find(band_ids.to_a)
[
{"_id": "...", "name": "Deftones" },
{"_id": "...", "name": "Tool"},
...
]

提示

前面的示例仅投影输出文档的 _id字段。 然后,它使用投影的结果查找文档并将它们作为 Mongoid::Document 模型实例返回。 运行聚合管道不需要此可选步骤。

要查看聚合操作符的完整列表,请参阅聚合操作符。

要了解如何组装聚合管道并查看示例,请参阅聚合管道。

要进一步了解本指南所讨论的任何方法,请参阅以下 API 文档: