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

聚合(Aggregation)

在本指南中,您可了解如何在 MongoDB Go 驱动程序中使用聚合操作

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

提示

完成聚合教程

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

聚合操作的运作方式与汽车工厂类似。汽车工厂内有一条装配线。装配线设有配备专门工具来完成特定作业的装配站。要制造汽车,需要将毛坯零件送到工厂。然后,装配线将零件改造并组装成汽车。

装配线类似于聚合管道,装配线上的装配站类似于聚合阶段,专用工具代表表达式运算符,而成品则类似于聚合结果

下表列出了通过使用查找和聚合操作来执行的任务。

查找操作
聚合操作




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

选择要返回的文档 选择要返回的字段



对结果进行排序 限制结果 计算结果
重命名字段 计算字段
汇总数据

分组值

聚合操作有局限性。执行聚合操作时,注意以下几点:

  • 返回的文档不得违反 BSON 文档大小限制(16 兆字节)。

  • 默认情况下,管道阶段的内存限制为 100 MB。如果需要,可使用 allowDiskUse() 方法超过此限制。

  • $graphLookup 阶段的内存严格限制为 100 MB,并忽略了 allowDiskUse 设置。

本部分的示例使用以下 Tea 结构作为 tea 集合中文档的模型:

type Tea struct {
Type string
Category string
Toppings []string
Price float32
}

要运行本部分中的示例,请通过使用以下代码段将示例数据加载到 db 数据库中的 tea 集合中:

coll := client.Database("db").Collection("tea")
docs := []any{
Tea{Type: "Masala", Category: "black", Toppings: []string{"ginger", "pumpkin spice", "cinnamon"}, Price: 6.75},
Tea{Type: "Gyokuro", Category: "green", Toppings: []string{"berries", "milk foam"}, Price: 5.65},
Tea{Type: "English Breakfast", Category: "black", Toppings: []string{"whipped cream", "honey"}, Price: 5.75},
Tea{Type: "Sencha", Category: "green", Toppings: []string{"lemon", "whipped cream"}, Price: 5.15},
Tea{Type: "Assam", Category: "black", Toppings: []string{"milk foam", "honey", "berries"}, Price: 5.65},
Tea{Type: "Matcha", Category: "green", Toppings: []string{"whipped cream", "honey"}, Price: 6.45},
Tea{Type: "Earl Grey", Category: "black", Toppings: []string{"milk foam", "pumpkin spice"}, Price: 6.15},
Tea{Type: "Hojicha", Category: "green", Toppings: []string{"lemon", "ginger", "milk foam"}, Price: 5.55},
}
result, err := coll.InsertMany(context.TODO(), docs)

每个文档都包含有关茶类型、可用配料和价格的信息。

以下示例计算并显示每个茶叶类别的平均评分和评分数量。

聚合管道使用 $group 阶段按 category 字段对文档进行分组,使用 $avg 表达式操作符计算平均值,并使用 $sum 表达式操作符计算文档数量。

groupStage := bson.D{
{"$group", bson.D{
{"_id", "$category"},
{"average_price", bson.D{{"$avg", "$price"}}},
{"type_total", bson.D{{"$sum", 1}}},
}}}
// Performs the aggregation and prints the results
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage})
if err != nil {
panic(err)
}
var results []bson.M
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
fmt.Printf("Average price of %v tea options: $%v \n", result["_id"], result["average_price"])
fmt.Printf("Number of %v tea options: %v \n\n", result["_id"], result["type_total"])
}
Average price of black tea options: $6.075
Number of black tea options: 4
Average price of green tea options: $5.70
Number of green tea options: 4

以下示例会匹配可使用牛奶泡沫作为配料的文档,并列出两种最便宜的选项。

聚合管道包含以下阶段:

  • $matchtoppings 字段包含“牛奶泡沫(milk foam)”的文档进行匹配的阶段

  • $unset 阶段,用于省略 _idcategory 字段

  • $sort 阶段按升序排序对 pricetoppings 进行排序

  • $limit 阶段以显示前两个文档

matchStage := bson.D{{"$match", bson.D{{"toppings", "milk foam"}}}}
unsetStage := bson.D{{"$unset", bson.A{"_id", "category"}}}
sortStage := bson.D{{"$sort", bson.D{{"price", 1}, {"toppings", 1}}}}
limitStage := bson.D{{"$limit", 2}}
// Performs the aggregation and prints the results
cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, unsetStage, sortStage, limitStage})
if err != nil {
panic(err)
}
var results []Tea
if err = cursor.All(context.TODO(), &results); err != nil {
panic(err)
}
for _, result := range results {
fmt.Printf("Tea: %v \nToppings: %v \nPrice: $%v \n\n", result.Type, strings.Join(result.Toppings, ", "), result.Price)
}
Tea: Hojicha
Toppings: lemon, ginger, milk foam
Price: $5.55
Tea: Gyokuro
Toppings: berries, milk foam
Price: $5.65

要了解有关所提及术语的更多信息,请参阅以下指南:

要查看更多聚合示例,请参阅以下指南:

要了解有关 Aggregate() 方法及其行为的更多信息,请参阅检索数据。

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