Aggregation in MongoDB ermöglicht die Durchführung komplexer Auswertungen und Analysen auf den in einer Datenbank gespeicherten Dokumenten. Statt einzelne Dokumente direkt auszugeben, können im Aggregationsprozess Teilergebnisse berechnet, gefiltert, gruppiert und durch verschiedene Transformationen verändert werden. Dies erleichtert es, aussagekräftige Reports, Statistiken und Analysen direkt innerhalb der Datenbank zu erzeugen, ohne die Daten erst zur weiteren Verarbeitung in externe Systeme übertragen zu müssen.
Die Aggregation in MongoDB basiert auf Pipelines, die aus einer Folge von Stages aufgebaut sind. Jede Stage erhält den Output der vorhergehenden Stage als Input, transformiert die Daten gemäß der darin definierten Operatoren und gibt das Ergebnis an die nächste Stage weiter. Dadurch entsteht eine flexible, erweiterbare und modular aufgebaute Verarbeitungskette.
Wichtige Konzepte: - Pipeline: Eine Sequenz von Verarbeitungsschritten (Stages). - Stage: Ein Verarbeitungsschritt, der bestimmte Operationen auf dem Dokumentstrom ausführt. - Operatoren: Spezielle Anweisungen, die innerhalb einer Stage verwendet werden, um Filter-, Gruppierungs-, Projektions- oder andere Transformationslogiken umzusetzen.
Eine Aggregations-Pipeline wird durch ein Array von Stages definiert.
Jede Stage beginnt typischerweise mit einem Operator wie
$match, $group, $project oder
$sort. Die Reihenfolge der Stages ist entscheidend für das
Endergebnis, da sich die Verarbeitungen voneinander ableiten.
Beispiele für typische Stages: - $match: Filtert
Dokumente basierend auf bestimmten Kriterien, ähnlich wie bei einer
normalen Query. - $project: Selektiert und transformiert
Felder, um nur noch relevante Informationen im Datenstrom zu behalten
oder neue Felder auf Basis existierender Werte abzuleiten. -
$group: Fasst Dokumente zu Gruppen zusammen, basierend auf
Schlüsselwerten und berechnet aggregierte Werte wie Summen,
Durchschnitte oder Counts. - $sort: Sortiert die Dokumente
nach bestimmten Feldern. - $limit und $skip:
Begrenzen oder überspringen eine festgelegte Anzahl von Dokumenten
innerhalb der Pipeline.
Innerhalb einer Stage, vor allem in $group und
$project, kommen verschiedene Operatoren zum Einsatz, um
Berechnungen durchzuführen oder Felder neu zu definieren. Wichtige
Operatoren sind: - Mathematische Operatoren wie $sum,
$avg, $min, $max. -
String-Operatoren wie $concat, $substr oder
$toLower. - Array-Operatoren wie $push,
$addToSet oder $size. - Logische Operatoren
wie $and, $or, $not. -
Konditionale Operatoren wie $cond, um abhängig von
Bedingungen unterschiedliche Werte zu erzeugen.
Um den Gesamtumsatz aus einer Sammlung von Bestellungen zu ermitteln,
kann eine Pipeline mit $group und $sum
verwendet werden. Angenommen, die Dokumente enthalten ein Feld
amount mit dem jeweiligen Bestellwert. Durch Gruppierung
aller Dokumente ohne einen gruppierenden Schlüssel (oder mit einem
konstanten Ausdruck) kann ein Gesamtwert berechnet werden.
db.orders.aggregate([
{ $group: { _id: null, totalAmount: { $sum: "$amount" } } }
])Diese Pipeline führt dazu, dass ein einzelnes Resultat zurückgegeben
wird, welches im Feld totalAmount die Summe aller
amount-Felder enthält.
Mit $lookup können Daten aus einer anderen Collection
eingebunden werden, um zum Beispiel zusätzliche Informationen zu
einzelnen Einträgen zu ergänzen. Dies ermöglicht join-ähnliche
Operationen innerhalb von MongoDB.
db.orders.aggregate([
{
$lookup: {
from: "customers",
localField: "customerId",
foreignField: "_id",
as: "customerInfo"
}
}
])Dadurch werden für jede Bestellung die passenden Kundendaten aus der
customers Collection in das Feld customerInfo
eingefügt.
Mit $project lassen sich Felder transformieren, um etwa
Felder umzubenennen, Felder auszublenden oder neue Felder auf Basis
existierender Daten zu berechnen.
db.orders.aggregate([
{
$project: {
_id: 0,
orderId: "$_id",
orderTotal: "$amount",
month: { $month: "$orderDate" }
}
}
])In diesem Beispiel werden vorhandene Felder umbenannt und ein neues
Feld month auf Basis des Datumsfelds orderDate
erzeugt.
Aggregation kann von Indexen profitieren, insbesondere wenn
$match und $sort früh in der Pipeline stehen
und Abfragen filtern oder sortieren, die von einem Index unterstützt
werden. Durch die geschickte Anordnung von Stages kann so die
Performance der Aggregation erheblich verbessert werden.
Empfehlungen zur Performance: - $match möglichst früh
verwenden, um die Datenmenge rasch einzuschränken. - $sort
möglichst früh und auf Felder anwenden, die indexiert sind. - Komplexe
Berechnungen und Transformationen erst nach effizienten Filter- und
Sortiervorgängen durchführen, um nur noch relevante Datenmengen
verarbeiten zu müssen.
In einem Sharded Cluster werden Aggregationspipelines verteilt ausgeführt. Jede Shard führt die Pipeline-Stages auf die lokalen Daten aus und liefert Teilergebnisse an den mongos, der dann weitere Stages anwendet. Werden Shard Keys und Indexe sinnvoll gewählt, können Aggregationsprozesse effizient über mehrere Shards parallelisiert werden.