Ten rozdział przedstawia szczegółowe wyjaśnienie analizy statystycznej w MongoDB, głównie osiągniętej za pomocą potoku agregacji. Jest podobny do instrukcji "group by" w SQL. W powłoce MongoDB, analiza statystyczna jest realizowana za pomocą funkcji db.collection.aggregate()
.
Samouczek wstępny
Ogólne kroki
- Użyj
$match
, aby filtrować docelowe dane - Użyj
$group
, aby zgrupować i obliczyć dane - Użyj
$sort
, aby opcjonalnie posortować wyniki
Dane testowe
Dane w kolekcji orders
wyglądają następująco
{ _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 }
Funkcja agregacji
db.collection.aggregate(pipeline)
Wyjaśnienie:
- Parametrem
pipeline
jest tablica, gdzie każdy element reprezentuje etap przetwarzania.
Przykład
db.orders.aggregate([
{ $match: { status: "A" } }, // Pierwszy etap
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, // Drugi etap
{ $sort: { total: -1 } } // Trzeci etap
])
Odpowiednik w SQL
select sum(amount) as total from orders
where status="A"
group by cust_id
order by total desc
Etap $match
Format:
{ $match: { <query> } }
Wyjaśnienie:
-
<query>
Warunki zapytania MongoDB
Służy do ustawiania warunków zapytania. Jeśli pominięto $match
, oznacza to zapytywanie wszystkich danych.
Wskazówka: Jeśli nie jesteś zaznajomiony z składnią zapytania MongoDB, prosimy o odwołanie się do poprzednich rozdziałów.
Etap $group
Podobnie jak klauzula group by
w SQL, służy do grupowania danych, a następnie wykonywania serii obliczeń statystycznych na zgrupowanych danych.
Podstawowe użycie $group
Składnia:
{
$group:
{
_id: <expression>, // Warunek grupowania, na przykład: grupuj według którego pola
<field1>: { <akumulator1> : <expression1> }, // Operacja agregacji, można dodać N operacji agregacji
...
}
}
Wyjaśnienie:
-
- Nazwa niestandardowego wskaźnika statystycznego, może ich być N w sumie -
- Funkcja agregacji, podobna do sumy SQL, średniej i innych funkcji agregacji, różnica polega na tym, że funkcje agregacji MongoDB są nazwane z prefiksem $, na przykład: $sum, $avg -
- Parametr funkcji agregacji, zazwyczaj wartość pola do zliczania, odwołując się do pól dokumentu za pomocą formatu "$nazwa pola"
Przykład:
db.orders.aggregate([
{
$group: {
_id: "$cust_id",
total: { $sum: "$amount" }, // Dodaj pierwszy wyliczony wskaźnik total, używając operatora sumy $sum
amount_avg: {$avg: "$amount"} // Dodaj drugi wyliczony wskaźnik avg, używając operatora obliczania średniej $avg
}
}
])
Wynik:
{ "_id" : "abc1", "total" : 75, "amount_avg" : 37.5 }
{ "_id" : "xyz1", "total" : 250, "amount_avg" : 83.33333333333333 }
Odpowiednik w SQL:
select
sum(amount) as total,
avg(amount) as amount_avg
from orders
group by cust_id
Funkcje agregacji $group
Powszechnie używane funkcje agregacji dla $group to:
Operator | Opis | Przykład |
---|---|---|
$avg | Oblicz średnią | {$avg: "$amount"} |
$sum | Suma | {$sum: "$amount"} |
$max | Wartość maksymalna | {$max: "$amount"} |
$min | Wartość minimalna | {$min: "$amount"} |
$first | Zwraca dane po grupowaniu, zawartość pierwszego dokumentu | {$first: "$amount"} |
$last | Zwraca dane po grupowaniu, zawartość ostatniego dokumentu | {$last: "$amount"} |
$push | Zwraca dane po grupowaniu | { $push: { ord_date: "$ord_date", amount: "$amount" } |
$addToSet | Zwraca dane po grupowaniu, różni się od $push, ponieważ usuwa duplikaty | { $addToSet: "$amount" } |
Przykład użycia $push
db.orders.aggregate(
[
{
$group:
{
_id: "$cust_id",
all: { $push: { ord_date: "$ord_date", amount: "$amount" } } // Wartości pól ord_date i 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 } ] }
Przykład użycia $addToSet
db.orders.aggregate(
[
{
$group:
{
_id: "$cust_id",
all_amount: { $addToSet: "$amount" } // Zwraca wszystkie unikalne wartości amount
}
}
]
)
Output
{ "_id" : "abc1", "all_amount" : [ 25, 50 ] }
{ "_id" : "xyz1", "all_amount" : [ 100, 25, 125 ] }
$sort:
Etap $sort jest zazwyczaj umieszczany na końcu, aby posortować zagregowane dane.
Format:
{ $sort: { <pole1>: <kolejność sortowania>, <pole2>: <kolejność sortowania> ... } }
Wyjaśnienie:
-
, - Nazwy pól do posortowania, obsługuje wiele pól. - <kolejność sortowania> - Kierunek sortowania, -1 dla malejącego, 1 dla rosnącego.
Przykład:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } }
])
Paginacja agregacji
Możemy zaimplementować paginację przy użyciu operatorów $limit i $skip.
Przykład:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 5 }, // Ogranicza liczbę zwróconych rekordów, podobnie jak rozmiar strony w paginacji.
{ $skip: 1 } // Pomija określoną liczbę rekordów, podobnie jak offset w SQL.
])