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

聚合(Aggregation)

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

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

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

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

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

查找操作
聚合操作




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

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



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

分组值

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

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

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

  • $graphLookup 阶段的内存限制为 100 兆字节,忽略 allowDiskUse 兆字节。

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

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

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

coll := client.Database("db").Collection("tea")docs := []interface{}{ 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 表达式操作符计算文档数量。

// create group stagegroupStage := bson.D{ {"$group", bson.D{ {"_id", "$category"}, {"average_price", bson.D{{"$avg", "$price"}}}, {"type_total", bson.D{{"$sum", 1}}}, }}} // pass the pipeline to the Aggregate() methodcursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage})if err != nil { panic(err)} // display the resultsvar results []bson.Mif 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"])}

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

聚合管道包含以下阶段:

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

  • $unset 阶段,用于省略 _id 和 category 字段

  • $sort 阶段按升序排序对 price 和 toppings 进行排序

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

// create the stagesmatchStage := 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}} // pass the pipeline to the Aggregate() methodcursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, unsetStage, sortStage, limitStage})if err != nil { panic(err)} // display the resultsvar results []Teaif 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)}

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

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

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

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