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

聚合(Aggregation)

在本指南中,您可以了解如何在 Rust 驱动程序中执行聚合操作。

聚合操作根据您在管道中设置的规范处理 MongoDB collection中的数据。聚合管道由一个或多个阶段组成。 每个阶段都根据其表达式操作符执行操作。 驱动程序执行聚合管道后,会返回聚合结果。

本指南包括以下部分:

提示

完成聚合教程

您可以在服务器手册的完整聚合管道教程部分找到详细解释常见聚合任务的教程。选择一个教程,然后从页面右上角的 Select your language 下拉菜单中选择 Rust

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

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

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

查找操作
聚合操作

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

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

执行聚合操作时,请考虑以下限制:

本节中的示例使用以下样本文档。 每个文档代表书评网站上的一个用户个人资料,并包含有关他们的姓名、年龄、类型兴趣以及他们最后一次活跃在网站上的日期的信息:

{ "name": "Sonya Mehta", "age": 23, "genre_interests": ["fiction", "mystery", "memoir"], "last_active": { "$date": "2023-05-13T00:00:00.000Z" } },
{ "name": "Selena Sun", "age": 45, "genre_interests": ["fiction", "literary", "theory"], "last_active": { "$date": "2023-05-25T00:00:00.000Z" } },
{ "name": "Carter Johnson", "age": 56, "genre_interests": ["literary", "self help"], "last_active": { "$date": "2023-05-31T00:00:00.000Z" } },
{ "name": "Rick Cortes", "age": 18, "genre_interests": ["sci-fi", "fantasy", "memoir"], "last_active": { "$date": "2023-07-01T00:00:00.000Z" } },
{ "name": "Belinda James", "age": 76, "genre_interests": ["literary", "nonfiction"], "last_active": { "$date": "2023-06-11T00:00:00.000Z" } },
{ "name": "Corey Saltz", "age": 29, "genre_interests": ["fiction", "sports", "memoir"], "last_active": { "$date": "2023-01-23T00:00:00.000Z" } },
{ "name": "John Soo", "age": 16, "genre_interests": ["fiction", "sports"], "last_active": { "$date": "2023-01-03T00:00:00.000Z" } },
{ "name": "Lisa Ray", "age": 39, "genre_interests": ["poetry", "art", "memoir"], "last_active": { "$date": "2023-05-30T00:00:00.000Z" } },
{ "name": "Kiran Murray", "age": 20, "genre_interests": ["mystery", "fantasy", "memoir"], "last_active": { "$date": "2023-01-30T00:00:00.000Z" } },
{ "name": "Beth Carson", "age": 31, "genre_interests": ["mystery", "nonfiction"], "last_active": { "$date": "2023-08-04T00:00:00.000Z" } },
{ "name": "Thalia Dorn", "age": 21, "genre_interests": ["theory", "literary", "fiction"], "last_active": { "$date": "2023-08-19T00:00:00.000Z" } },
{ "name": "Arthur Ray", "age": 66, "genre_interests": ["sci-fi", "fantasy", "fiction"], "last_active": { "$date": "2023-11-27T00:00:00.000Z" } }

以下示例计算对每种类型感兴趣的用户的平均年龄、最小年龄和最大年龄。

聚合管道包含以下阶段:

  • $unwind阶段,用于将genre_interests字段中的每个数组条目分隔成新文档。

  • $group阶段,用于按genre_interests字段的值对文档进行分组。 此阶段使用$avg$min$max操作符查找用户的平均年龄、最小年龄和最大年龄。

let age_pipeline = vec![
doc! { "$unwind": doc! { "path": "$genre_interests" } },
doc! { "$group": doc! {
"_id": "$genre_interests",
"avg_age": doc! { "$avg": "$age" },
"min_age": doc! { "$min": "$age" },
"max_age": doc! { "$max": "$age" }
} }
];
let mut results = my_coll.aggregate(age_pipeline).await?;
while let Some(result) = results.try_next().await? {
println!("* {:?}", result);
}
* { "_id": "memoir", "avg_age": 25.8, "min_age": 18, "max_age": 39 }
* { "_id": "sci-fi", "avg_age": 42, "min_age": 18, "max_age": 66 }
* { "_id": "fiction", "avg_age": 33.333333333333336, "min_age": 16, "max_age": 66 }
* { "_id": "nonfiction", "avg_age": 53.5, "min_age": 31, "max_age": 76 }
* { "_id": "self help", "avg_age": 56, "min_age": 56, "max_age": 56 }
* { "_id": "poetry", "avg_age": 39, "min_age": 39, "max_age": 39 }
* { "_id": "literary", "avg_age": 49.5, "min_age": 21, "max_age": 76 }
* { "_id": "fantasy", "avg_age": 34.666666666666664, "min_age": 18, "max_age": 66 }
* { "_id": "mystery", "avg_age": 24.666666666666668, "min_age": 20, "max_age": 31 }
* { "_id": "theory", "avg_age": 33, "min_age": 21, "max_age": 45 }
* { "_id": "art", "avg_age": 39, "min_age": 39, "max_age": 39 }
* { "_id": "sports", "avg_age": 22.5, "min_age": 16, "max_age": 29 }

以下示例查找每个月的最后活跃用户数。

聚合管道包含以下阶段:

  • $project 阶段将 last_active字段中的月份作为数字提取到 month_last_active字段

  • $group 阶段按 month_last_active字段对文档进行群组并计算每个月的文档数量

  • $sort 阶段对月份设立升序排序

let last_active_pipeline = vec![
doc! { "$project": { "month_last_active" : doc! { "$month" : "$last_active" } } },
doc! { "$group": doc! { "_id" : doc! {"month_last_active": "$month_last_active"} ,
"number" : doc! { "$sum" : 1 } } },
doc! { "$sort": { "_id.month_last_active" : 1 } }
];
let mut results = my_coll.aggregate(last_active_pipeline).await?;
while let Some(result) = results.try_next().await? {
println!("* {:?}", result);
}
* { "_id": { "month_last_active": 1 }, "number": 3 }
* { "_id": { "month_last_active": 5 }, "number": 4 }
* { "_id": { "month_last_active": 6 }, "number": 1 }
* { "_id": { "month_last_active": 7 }, "number": 1 }
* { "_id": { "month_last_active": 8 }, "number": 2 }
* { "_id": { "month_last_active": 11 }, "number": 1 }

以下示例根据三种最受欢迎的类型在用户兴趣中出现的频率来查找它们。

聚合管道包含以下阶段:

  • $unwind 阶段将 genre_interests字段中的每个大量条目分隔到新文档中

  • $group 阶段按 genre_interests字段对文档进行群组并计算每种类型的文档数量

  • $sort 阶段对流派受欢迎程度设立降序排序

  • $limit 仅显示前三种类型的阶段

let popularity_pipeline = vec![
doc! { "$unwind" : "$genre_interests" },
doc! { "$group" : doc! { "_id" : "$genre_interests" , "number" : doc! { "$sum" : 1 } } },
doc! { "$sort" : doc! { "number" : -1 } },
doc! { "$limit": 3 }
];
let mut results = my_coll.aggregate(popularity_pipeline).await?;
while let Some(result) = results.try_next().await? {
println!("* {:?}", result);
}
* { "_id": "fiction", "number": 6 }
* { "_id": "memoir", "number": 5 }
* { "_id": "literary", "number": 4 }

要了解有关本指南中提到的概念的更多信息,请参阅以下服务器手册条目:

要了解有关aggregate()方法行为的更多信息,请参阅“检索数据”指南的“聚合操作”部分。

要学习;了解有关在聚合管道中对结果进行排序的更多信息,请参阅排序指南。

您可以使用MongoDB Vector Search功能对向量嵌入执行相似性搜索。要了解更多信息,请参阅MongoDB 向量搜索指南。

要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档: