Dieses Kapitel führt eine detaillierte Erklärung der statistischen Analyse von MongoDB ein, die hauptsächlich über die Aggregation Pipeline erreicht wird. Sie ähnelt der "group by"-Anweisung in SQL. In der MongoDB-Shell wird die statistische Analyse mit der Funktion db.collection.aggregate()
implementiert.
Voraussetzung Tutorial
Allgemeine Schritte
- Verwenden von
$match
, um die Ziel-Daten zu filtern - Verwenden von
$group
, um die Daten zu gruppieren und zu berechnen - Verwenden von
$sort
, um die Ergebnisse zu sortieren (optional)
Testdaten
Die Daten in der orders
-Sammlung sehen wie folgt aus
{ _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 }
aggregate-Funktion
db.collection.aggregate(pipeline)
Erklärung:
- Die
pipeline
nimmt einen Array-Parameter an, wobei jedes Element eine Verarbeitungsstufe darstellt.
Beispiel
db.orders.aggregate([
{ $match: { status: "A" } }, // Erste Stufe
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, // Zweite Stufe
{ $sort: { total: -1 } } // Dritte Stufe
])
Äquivalentes SQL
select sum(amount) as total from orders
where status="A"
group by cust_id
order by total desc
$match-Stufe
Format:
{ $match: { <Abfrage> } }
Erklärung:
-
<Abfrage>
MongoDB-Abfragebedingungen
Wird verwendet, um Abfragebedingungen festzulegen. Wenn $match
ignoriert wird, impliziert dies die Abfrage aller Daten.
Tipp: Wenn Sie mit der MongoDB-Abfragesyntax nicht vertraut sind, lesen Sie bitte die vorherigen Kapitel.
$group-Stufe
Ähnlich wie die group by
-Klausel in SQL wird sie verwendet, um die Daten zu gruppieren und dann eine Reihe statistischer Berechnungen an den gruppierten Daten durchzuführen.
Grundlegende Verwendung von $group
Syntax:
{
$group:
{
_id: <Ausdruck>, // Gruppierungsbedingung, z.B.: nach welchem Feld gruppieren
<Feld1>: { <Aggregator1> : <Ausdruck1> }, // Aggregationsoperation, Sie können N Aggregationsoperationen hinzufügen
...
}
}
Erklärung:
-
- Name des benutzerdefinierten statistischen Indikators, kann insgesamt N sein -
- Aggregationsfunktion, ähnlich wie sum, avg und andere Aggregationsfunktionen in SQL, der Unterschied besteht darin, dass die Aggregationsfunktionen in MongoDB mit $ als Präfix benannt sind, z.B.: $sum, $avg -
- Parameter der Aggregationsfunktion, normalerweise der zu zählende Feldwert, unter Verwendung des Formats "$Feldname" zur Referenzierung von Dokumentfeldern
Beispiel:
db.orders.aggregate([
{
$group: {
_id: "$cust_id",
total: { $sum: "$amount" }, // Der erste berechnete Indikator total, unter Verwendung des Summierungsoperators $sum
amount_avg: {$avg: "$amount"} // Der zweite berechnete Indikator avg, unter Verwendung des Durchschnittsberechnungsoperators $avg
}
}
])
Ausgabe:
{ "_id" : "abc1", "total" : 75, "amount_avg" : 37,5 }
{ "_id" : "xyz1", "total" : 250, "amount_avg" : 83,33333333333333 }
Äquivalentes SQL:
select
sum(amount) as total,
avg(amount) as amount_avg
from orders
group by cust_id
$group-Aggregationsfunktionen
Die üblicherweise verwendeten Aggregationsfunktionen für $group sind wie folgt:
Operator | Beschreibung | Beispiel |
---|---|---|
$avg | Durchschnitt berechnen | {$avg: "$amount"} |
$sum | Summe berechnen | {$sum: "$amount"} |
$max | Maximalwert | {$max: "$amount"} |
$min | Minimalwert | {$min: "$amount"} |
$first | Nach Gruppierung Daten zurückgeben, den Inhalt des ersten Dokuments | {$first: "$amount"} |
$last | Nach Gruppierung Daten zurückgeben, den Inhalt des letzten Dokuments | {$last: "$amount"} |
$push | Nach Gruppierung Daten zurückgeben | { $push: { ord_date: "$ord_date", amount: "$amount" } |
$addToSet | Nach Gruppierung Daten zurückgeben, anders als $push, da Duplikate entfernt werden | { $addToSet: "$amount" } |
Beispiel für $push
db.orders.aggregate(
[
{
$group:
{
_id: "$cust_id",
all: { $push: { ord_date: "$ord_date", amount: "$amount" } } // Werte der Felder ord_date und amount
}
}
]
)
Ausgabe
{ "_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 } ] }
Beispiel für $addToSet
db.orders.aggregate(
[
{
$group:
{
_id: "$cust_id",
all_amount: { $addToSet: "$amount" } // Gibt alle verschiedenen Betragswerte zurück
}
}
]
)
Ausgabe
{ "_id" : "abc1", "all_amount" : [ 25, 50 ] }
{ "_id" : "xyz1", "all_amount" : [ 100, 25, 125 ] }
$sort:
Die $sort-Phase wird typischerweise am Ende platziert, um die aggregierten Daten zu sortieren.
Format:
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
Erklärung:
-
, - Die Namen der zu sortierenden Felder, unterstützt mehrere Felder. -
- Die Sortierrichtung, -1 für absteigend, 1 für aufsteigend.
Beispiel:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } }
])
Aggregat-Paginierung
Wir können die Paginierung mithilfe der $limit- und $skip-Operatoren implementieren.
Beispiel:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 5 }, // Begrenzt die Anzahl der zurückgegebenen Datensätze, ähnlich wie die Seitengröße bei der Paginierung.
{ $skip: 1 } // Überspringt eine bestimmte Anzahl von Datensätzen, ähnlich wie der Offset in SQL.
])