聚合
概述
在本指南中,您可以学习如何在MongoDB Go驱动程序中使用聚合操作。
聚合操作根据您在聚合管道中的指定处理MongoDB集合中的数据。聚合管道由一个或多个阶段组成。每个阶段根据其表达式运算符执行操作。驱动程序执行聚合管道后,返回聚合结果。
类比
聚合操作类似于汽车工厂。汽车工厂有装配线。装配线上有装配站,配备专门工具执行特定任务。要制造汽车,您将原材料发送到工厂。然后,装配线将部件转换并组装成汽车。
装配线类似于聚合管道,装配站类似于装配线上的聚合阶段,专用工具代表的是表达式运算符,成品则类似于聚合结果。
比较操作
以下表格列出了您可以使用find和聚合操作执行的任务。
查找操作 | 聚合操作 |
---|---|
选择返回的文档内容 选择返回的字段 排序结果 限制结果 计数结果 | 选择返回的文档内容 选择返回的字段 排序结果 限制结果 计数结果 重命名字段 计算字段 总结数据 分组值 |
限制
聚合操作有限制。在执行聚合操作时,请注意以下事项
返回的文档必须不违反BSON 文档大小限制,为16兆字节。
默认情况下,管道阶段具有100兆字节的内存限制。如果需要,您可以使用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 stage groupStage := 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() method cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{groupStage}) if err != nil { panic(err) } // display the results 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
在结果中省略字段
以下示例匹配可以添加奶泡的文档,并列出两个最便宜的选择。
聚合管道包含以下阶段
$match
阶段匹配包含 "milk foam" 的toppings
字段的文档$unset
阶段省略_id
和category
字段$sort
阶段按升序排序price
和toppings
$limit
阶段显示前两个文档
// create the stages 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}} // pass the pipeline to the Aggregate() method cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, unsetStage, sortStage, limitStage}) if err != nil { panic(err) } // display the results 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 文档
要了解更多关于本指南中讨论的任何方法或类型的信息,请参阅以下 API 文档