Docs 菜单
Docs 主页
/ / /
Go 驱动程序
/

聚合(Aggregation)

在此页面上

  • Overview
  • 比较操作
  • 限制
  • 示例
  • 更多信息

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

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

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

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

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

查找操作
聚合操作
Select what documents to return
Select which fields to return
Sort the results
Limit the results
Count the results
Select what documents to return
Select which fields to return
Sort the results
Limit the results
Count the results
Rename fields
Calculate fields
Summarize data
Group values

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

  • 返回的文档不得违反 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 := []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"])
}

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

聚合管道包含以下阶段:

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

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

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

  • $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)
}

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

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

  • 数数

  • Limit

  • 跳过

  • Text

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

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

后退

修改 CRUD 操作的执行