Similar to the analysis by Group by in SQL, MongoDB also supports it. This chapter introduces how to implement the statistical analysis of MongoDB data using Golang.

Tutorial Prerequisites

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" } },  // La primera etapa, coincidencia de datos de documentos en función de los criterios de consulta
    { $group: { _id: "$cust_id", total: { $sum: "$amount" } } },   // La segunda etapa, agrupación y agregación
    { $sort: { total: -1 } }  // La tercera etapa, ordenando los resultados
]

SQL equivalente:

select sum(amount) as total from orders 
        where status="A" 
        group by cust_id 
        order by total desc

Aquí tienes cómo lograr lo mismo en 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
	
	// El código para conectar a MongoDB y obtener objetos de colección se omite aquí y se puede consultar en el tutorial de inicio rápido.

	// Expresión de análisis estadístico, utilizando estructuras de datos de Golang para representar la sintaxis nativa de MongoDB.
	// Si no estás familiarizado con el modelo de datos de MongoDB de Golang, consulta las secciones anteriores.
	pipeline := mongo.Pipeline{
			{{"$match", bson.D{{"status", "A"}}}},
			{{"$group", bson.D{{"_id", "$cust_id"}, {"total", bson.D{{"$sum", "$amount"}}}}}},
			{{"$sort", bson.D{{"total", -1}}}
	}
	
	// Establecer tiempo de espera
	opts := options.Aggregate().SetMaxTime(2 * time.Second)
	
	// Realizar análisis estadístico
	cursor, err := coll.Aggregate(
								context.TODO(),  // Parámetro de contexto
								pipeline,  // Expresión de análisis estadístico
								opts // Parámetros opcionales
							)
	if err != nil {
		log.Fatal(err)
	}

	// Definir el conjunto de resultados, utilizando el tipo bson.M (un tipo de estructura de mapa) para almacenar los resultados de la consulta
	var results []bson.M
	// Obtener todos los resultados y almacenarlos en la variable de resultados
	if err = cursor.All(context.TODO(), &results); err != nil {
		log.Fatal(err)
	}
	
	// Iterar a través de los resultados de la consulta
	for _, result := range results {
		fmt.Printf("id =  %v , total =  %v \n", result["_id"], result["total"])
	}
}

Consejo: Para obtener más sintaxis de agregación de MongoDB, consulta MongoDB Aggregation Pipeline