Hai un negozio e-commerce con ordini, clienti e prodotti in collezioni separate. Ogni giorno hai bisogno di sapere il totale speso per cliente, la categoria più venduta, o i prodotti mai ordinati. Con MongoDB, la risposta non è una query semplice: è una aggregation pipeline.
Noi, di Meteora Web, usiamo la pipeline di MongoDB da anni per analisi di magazzino, report di fatturato e dashboard in tempo reale. Veniamo dalla contabilità: sappiamo che un dato aggregato senza contesto vale zero. Per questo vogliamo mostrarti come usare $group, $match, $lookup e $project per estrarre informazioni reali, senza girare in tondo tra collezioni.
Questa guida è per chi ha già dimestichezza con MongoDB e vuole padroneggiare la pipeline. Niente teoria astratta: solo codice che funziona e ragionamenti sul perché ogni stadio conviene.
Come funziona $match per filtrare i documenti nella pipeline MongoDB?
$match è il filtro di ingresso. Va messo il prima possibile nella pipeline: meno documenti passano agli stadi successivi, più veloce è l'esecuzione. È identico a una query di find, ma dentro la pipeline.
Sponsored Protocol
Esempio pratico: ordini di un mese specifico
Supponiamo una collezione ordini con campi data, totale, cliente_id. Vogliamo solo gli ordini di gennaio 2026.
db.ordini.aggregate([
{ $match: { data: { $gte: ISODate("2026-01-01"), $lt: ISODate("2026-02-01") } } }
])Attenzione: $match sfrutta gli indici. Se il campo data è indicizzato, la query è fulminea. Lo vediamo spesso nei progetti che ci arrivano: pipeline lente perché $match arriva dopo $group. Invertite l'ordine e il tempo si dimezza.
Cosa fare subito: Controlla le tue pipeline esistenti: il primo stadio è un $match? Se no, spostalo all'inizio.
Quanto è potente $group per aggregare e calcolare metriche nella pipeline MongoDB?
$group raggruppa documenti per una chiave e applica accumulatori come $sum, $avg, $max, $push. È il cuore delle statistiche.
Esempio: totale vendite per cliente
db.ordini.aggregate([
{ $match: { data: { $gte: ISODate("2026-01-01"), $lt: ISODate("2026-02-01") } } },
{ $group: { _id: "$cliente_id", totale_speso: { $sum: "$totale" }, numero_ordini: { $sum: 1 } } }
])Il risultato: per ogni cliente, il totale speso e il conteggio ordini. Nota: $group non può usare indici direttamente, ma se hai filtrato con $match prima, lavora su un set ridotto.
Sponsored Protocol
Accumulatori da ricordare:
$sum– somma numerica$avg– media$min/$max– valori estremi$push– crea array di tutti i valori raggruppati$addToSet– array di valori unici
Noi usiamo $push per generare report di magazzino: raggruppiamo per fornitore e mettiamo in array i codici prodotto.
Come si usa $lookup per join tra collezioni in una pipeline MongoDB?
$lookup è l'equivalente di un LEFT JOIN SQL. Permette di unire documenti da un'altra collezione in base a un campo comune. Attenzione: non è gratis. Ogni $lookup aggiunge latenza, specialmente su collezioni grandi.
Sponsored Protocol
Esempio: arricchire gli ordini con i dati cliente
Collezione clienti con _id e nome. Vogliamo unire ogni ordine al nome del cliente.
db.ordini.aggregate([
{ $match: { data: { $gte: ISODate("2026-01-01"), $lt: ISODate("2026-02-01") } } },
{ $lookup: {
from: "clienti",
localField: "cliente_id",
foreignField: "_id",
as: "cliente"
} },
{ $unwind: "$cliente" } // se vuoi il documento singolo, non array
])Ottimizzazione: dopo $lookup, usa $unwind solo se necessario. Altrimenti, se lasci l'array, puoi usare $project per estrarre il primo elemento. Inoltre, indicizza il campo _id su clienti (è già indicizzato di default) e su cliente_id su ordini.
Un errore comune: fare $lookup su collezioni non indicizzate. Lo vediamo ogni giorno – il sistema va in timeout. Metti un indice composto se necessario.
Come ottimizzare le pipeline con $project nella pipeline MongoDB?
$project modella il documento in uscita: seleziona, rinomina, calcola nuovi campi. Serve a due scopi: ridurre la mole di dati trasferita e creare strutture leggibili per l'applicazione.
Sponsored Protocol
Esempio: ripulire il risultato dopo un $lookup
Dopo l'unione, vogliamo solo cliente.nome, totale, data. Niente campi interni.
db.ordini.aggregate([
// ... stadi precedenti ...
{ $project: {
_id: 0,
cliente: "$cliente.nome",
totale: 1,
data: 1
} }
])Puoi anche usare $addFields (o $set) se vuoi aggiungere campi senza eliminare gli esistenti. Noi preferiamo $project per tenere pulito il risultato finale, specialmente quando inviamo dati a un frontend.
Attenzione ai campi calcolati: non usare $project per espressioni troppo pesanti. Meglio calcolare prima in un $addFields e poi proiettare.
Cosa fare adesso con la pipeline di aggregazione MongoDB
Ecco tre azioni concrete da eseguire oggi:
- Analizza una pipeline esistente – Apri il profiler di MongoDB Atlas o usa
explain()per vedere se$matchè il primo stadio e se sfrutta gli indici. - Crea un report di raggruppamento – Prendi una collezione con dati reali (es. ordini, log) e scrivi una pipeline con
$match+$group. Misura il tempo di esecuzione. - Integra un $lookup – Unisci due collezioni che usi spesso e verifica la performance con
explain(). Aggiungi un indice se serve.
Ricorda: la pipeline di aggregazione è uno strumento potente, ma va usata con cognizione di causa. Ogni stadio ha un costo. Noi, di Meteora Web, abbiamo ottimizzato centinaia di pipeline per clienti e-commerce, riducendo i tempi da minuti a secondi. Un sito si misura in fatturato, non in complimenti. Una pipeline lenta perde clienti e vendite.
Sponsored Protocol
Per approfondire l'intero mondo dei database NoSQL, leggi la nostra guida pillar su MongoDB e Database NoSQL. E se vuoi un confronto con Redis per messaggistica, abbiamo scritto Redis Pub/Sub.
Riferimento ufficiale: MongoDB Aggregation Pipeline Documentation.