Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
bucket groups continuous numeric values into defined ranges — the building block for histograms, price range filters, and age distribution charts. Understanding these stages matters because the naive alternative is running three queries and merging results in application code, which is 3× the database load, 3× the latency, and produces inconsistent snapshots since each query runs at a different moment.
Compute category counts and price-range buckets in a single aggregation pass using $facet.
topByRating that uses $sort and $limit to return the top 3 highest-rated products. Confirm all three facets return consistent results from the same pipeline invocation.buckets: 4 instead of manual boundaries. Compare the auto-generated boundaries to your manual ones. Note which approach produces more even distribution for your dataset.Use these three in order. Each builds on the one before.
Explain MongoDB's $facet stage. What problem does it solve compared to running multiple separate aggregations?
When $facet runs two sub-pipelines, does MongoDB read the input documents once or twice? What are the memory implications for large input sets?
I'm building a product search page that needs category counts, price range counts, and brand counts all computed at query time. Design a $facet pipeline that also accepts a user's filter (e.g. selected category) and correctly shows counts for the other facets as if that filter is applied.
package main
import (
"context"; "fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
client, _ := mongo.Connect(context.TODO(), options.Client().ApplyURI("mongodb://localhost:27017"))
col := client.Database("demo").Collection("products")
pipeline := bson.A{
bson.D{{"$facet", bson.D{
{"byCategory", bson.A{
bson.D{{"$group", bson.D{{"_id", "$category"}, {"count", bson.D{{"$sum", 1}}}}}},
}},
{"byPriceRange", bson.A{
bson.D{{"$bucket", bson.D{
{"groupBy", "$price"},
{"boundaries", bson.A{0, 25, 50, 100, 200}},
{"default", "200+"},
{"output", bson.D{{"count", bson.D{{"$sum", 1}}}, {"avgPrice", bson.D{{"$avg", "$price"}}}}}},
}}},
}},
}}},
}
cursor, _ := col.Aggregate(context.TODO(), pipeline)
var results []bson.M
cursor.All(context.TODO(), &results)
fmt.Println(results[0])
}go run main.go