Similar to SQL’s Group by analysis, MongoDB also supports it. This chapter introduces how to implement statistical analysis of MongoDB data using Golang.
Prerequisite Tutorial
Please read the prerequisite tutorial below:
Test Data
The data in the orders collection is as follows:
{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }
Grouping and Aggregation
Perform statistical queries using the Collection.Aggregate function.
Below is an example of statistical analysis in MongoDB:
[
{ $match: { status: "A" } }, // The first stage, matching document data based on query criteria
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, // The second stage, grouping and aggregation
{ $sort: { total: -1 } } // The third stage, sorting the results
]
Equivalent SQL:
select sum(amount) as total from orders
where status="A"
group by cust_id
order by total desc
Here’s how to achieve the same in Golang:
package main
import (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
var coll *mongo.Collection
// The code for connecting to MongoDB and obtaining collection objects is omitted here and can be referred to in the quick start tutorial.
// Statistical analysis expression, using Golang data structure to represent the MongoDB native syntax.
// If you are not familiar with the Golang MongoDB data model, please refer to the previous sections.
pipeline := mongo.Pipeline{
{{"$match", bson.D{{"status", "A"}}}},
{{"$group", bson.D{{"_id", "$cust_id"}, {"total", bson.D{{"$sum", "$amount"}}}}}},
{{"$sort", bson.D{{"total", -1}}}
}
// Set timeout
opts := options.Aggregate().SetMaxTime(2 * time.Second)
// Perform statistical analysis
cursor, err := coll.Aggregate(
context.TODO(), // Context parameter
pipeline, // Statistical analysis expression
opts // Optional parameters
)
if err != nil {
log.Fatal(err)
}
// Define the result set, using the bson.M type (a type of map structure) to store the query results
var results []bson.M
// Get all results and store them in the results variable
if err = cursor.All(context.TODO(), &results); err != nil {
log.Fatal(err)
}
// Iterate through the query results
for _, result := range results {
fmt.Printf("id = %v , total = %v \n", result["_id"], result["total"])
}
}
Tip: For more MongoDB aggregation syntax, please refer to MongoDB Aggregation Pipeline