Questo capitolo introduce una spiegazione dettagliata dell'analisi statistica di MongoDB, principalmente realizzata attraverso l'Aggregation Pipeline. È simile allo statement "group by" in SQL. Nella shell di MongoDB, l'analisi statistica è implementata utilizzando la funzione db.collection.aggregate()
.
Tutorial Prerequisiti
Passaggi Generali
- Utilizzare
$match
per filtrare i dati di destinazione - Utilizzare
$group
per raggruppare e calcolare i dati - Utilizzare
$sort
per ordinare i risultati (opzionale)
Dati di Test
I dati nella collezione orders
sono i seguenti
{ _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 }
Funzione di aggregazione
db.collection.aggregate(pipeline)
Spiegazione:
- Il
pipeline
prende un parametro array, dove ciascun elemento rappresenta una fase di elaborazione.
Esempio
db.orders.aggregate([
{ $match: { status: "A" } }, // Prima fase
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, // Seconda fase
{ $sort: { total: -1 } } // Terza fase
])
Equivalente SQL
select sum(amount) as total from orders
where status="A"
group by cust_id
order by total desc
Fase $match
Formato:
{ $match: { <query> } }
Spiegazione:
-
<query>
condizioni di interrogazione MongoDB
Viene utilizzato per impostare le condizioni di interrogazione. Se si ignora $match
, implica l'interrogazione di tutti i dati.
Suggerimento: se non si è familiarizzati con la sintassi di interrogazione di MongoDB, fare riferimento ai capitoli precedenti.
Fase $group
Simile alla clausola group by
in SQL, viene utilizzata per raggruppare i dati e quindi eseguire una serie di calcoli statistici sui dati raggruppati.
Utilizzo di base di $group
Sintassi:
{
$group:
{
_id: <espressione>, // Condizione di raggruppamento, ad esempio: raggruppa per quale campo
<campo1>: { <accumulator1> : <espressione1> }, // Operazione di aggregazione, è possibile aggiungere N operazioni di aggregazione
...
}
}
Spiegazione:
-
- Nome dell'indicatore statistico personalizzato, possono esserci N in totale -
- Funzione di aggregazione, simile a sum, avg e altre funzioni di aggregazione di SQL, la differenza è che le funzioni di aggregazione di MongoDB sono nominate con $ come prefisso, ad esempio: $sum, $avg -
- Parametro della funzione di aggregazione, di solito il valore del campo da contare, facendo riferimento ai campi del documento utilizzando il formato "$nome campo"
Esempio:
db.orders.aggregate([
{
$group: {
_id: "$cust_id",
total: { $sum: "$amount" }, // Aggiungi il primo indicatore calcolato totale, utilizzando l'operatore di somma $sum
amount_avg: {$avg: "$amount"} // Aggiungi il secondo indicatore calcolato avg, utilizzando l'operatore di calcolo della media $avg
}
}
])
Output:
{ "_id" : "abc1", "total" : 75, "amount_avg" : 37.5 }
{ "_id" : "xyz1", "total" : 250, "amount_avg" : 83.33333333333333 }
Equivalente SQL:
select
sum(amount) as total,
avg(amount) as amount_avg
from orders
group by cust_id
Funzioni di Aggregazione di $group
Le funzioni di aggregazione comuni per $group sono le seguenti:
Operatore | Descrizione | Esempio |
---|---|---|
$avg | Calcola la media | {$avg: "$amount"} |
$sum | Somma | {$sum: "$amount"} |
$max | Valore massimo | {$max: "$amount"} |
$min | Valore minimo | {$min: "$amount"} |
$first | Restituisce i dati dopo l'aggregazione, il contenuto del primo documento | {$first: "$amount"} |
$last | Restituisce i dati dopo l'aggregazione, il contenuto dell'ultimo documento | {$last: "$amount"} |
$push | Restituisce i dati dopo l'aggregazione | { $push: { ord_date: "$ord_date", amount: "$amount" } |
$addToSet | Restituisce i dati dopo l'aggregazione, differente da $push poiché rimuove i duplicati | { $addToSet: "$amount" } |
Esempio di $push
db.ordini.aggregate(
[
{
$group:
{
_id: "$cust_id",
all: { $push: { ord_date: "$ord_date", amount: "$amount" } } // Valori dei campi ord_date e amount
}
}
]
)
Output
{ "_id" : "abc1", "all" : [ { "ord_date" : "2021-04-18 00:00:00", "amount" : 50 }, { "ord_date" : "2021-04-21 00:00:00", "amount" : 25 } ] }
{ "_id" : "xyz1", "all" : [ { "ord_date" : "2021-04-18 00:00:00", "amount" : 100 }, { "ord_date" : "2021-04-20 00:00:00", "amount" : 25 }, { "ord_date" : "2021-04-21 00:00:00", "amount" : 125 } ] }
Esempio di $addToSet
db.ordini.aggregate(
[
{
$group:
{
_id: "$cust_id",
all_amount: { $addToSet: "$amount" } // Restituisce tutti i valori distinti di amount
}
}
]
)
Output
{ "_id" : "abc1", "all_amount" : [ 25, 50 ] }
{ "_id" : "xyz1", "all_amount" : [ 100, 25, 125 ] }
$sort:
Lo stage $sort è tipicamente posizionato alla fine per ordinare i dati aggregati.
Formato:
{ $sort: { <campo1>: <ordine di ordinamento>, <campo2>: <ordine di ordinamento> ... } }
Spiegazione:
-
, - I nomi dei campi da ordinare, supporta più campi. -
- La direzione dell'ordinamento, -1 per decrescente, 1 per crescente.
Esempio:
db.ordini.aggregate([
{ $match: { stato: "A" } },
{ $group: { _id: "$cust_id", totale: { $sum: "$amount" } } },
{ $sort: { totale: -1 } }
])
Paginazione dell'Aggregato
Possiamo implementare la paginazione utilizzando gli operatori $limit e $skip.
Esempio:
db.ordini.aggregate([
{ $match: { stato: "A" } },
{ $group: { _id: "$cust_id", totale: { $sum: "$amount" } } },
{ $sort: { totale: -1 } },
{ $limit: 5 }, // Limita il numero di record restituiti, simile alla dimensione della pagina nella paginazione.
{ $skip: 1 } // Salta un certo numero di record, simile all'offset in SQL.
])