Docs Menu

Docs HomeGo Driver

Aggregation

On this page

  • Overview
  • Compare Operations
  • Limitations
  • Examples
  • Additional Information

In this guide, you can learn how to use aggregation operations in the MongoDB Go Driver.

Aggregation operations process data in your MongoDB collections based on your specifications in the aggregation pipeline. An aggregation pipeline consists of one or more stages. Each stage performs an operation based on its expression operators. After the driver executes the aggregation pipeline, it returns an aggregated result.

Aggregation operations operate similarly to a car factory. Car factories have an assembly line. The assembly lines have assembly stations with specialized tools to perform a specific task. To build a car, you send raw parts to the factory. Then, the assembly line transforms and assembles the parts into a car.

The assembly line resembles the aggregation pipeline, the assembly stations in the assembly line resemble the aggregation stages, the specialized tools represent the expression operators, and the finished product resembles the aggregated result.

The following table lists the tasks you can perform by using find and aggregation operations.

Find Operations
Aggregation Operations
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

Aggregation operations have limitations. When performing aggregation operations, keep the following in mind:

  • Returned documents must not violate the BSON document size limit of 16 megabytes.

  • Pipeline stages have a memory limit of 100 megabytes by default. If required, you may exceed this limit by using the allowDiskUse method.

  • The $graphLookup stage has a strict memory limit of 100 megabytes and ignores allowDiskUse.

The examples in this section use the following Tea struct as a model for documents in the tea collection:

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

To run the examples in this section, load the sample data into the tea collection in the db database by using the following snippet:

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)

Each document contains information about the tea type, the available toppings, and the price.

The following example calculates and displays the average rating and number of ratings for each tea category.

The aggregation pipeline uses the $group stage to group the documents by the category field, calculates the average using the $avg expression operator, and counts the number of documents using the $sum expression operator.

// 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"])
}

The following example matches documents where you can get milk foam as a topping and lists the two cheapest options.

The aggregation pipeline contains the following stages:

  • $match stage to match documents where the toppings field contains "milk foam"

  • $unset stage to omit the _id and category fields

  • $sort stage to sort the price and toppings in ascending order

  • $limit stage to show the first two documents

// 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)
}

To learn more about the terms mentioned, see the following guides:

To view more aggregation examples, see the following guides:

To learn more about the Aggregate() method and its behavior, see Retrieve Data.

To learn more about any of the methods or types discussed in this guide, see the following API Documentation:

←  Modify Execution of CRUD OperationsIndexes →