Jenseits der Grundlagen: Erweiterte MongoDB-Abfragebefehle für die Datenanalyse
Verwenden Sie erweiterte MongoDB-Filter, Projektionen und Aggregationsstufen, um Daten zu analysieren, ohne sie aus der Datenbank zu verschieben.
Jenseits der Grundlagen: Erweiterte MongoDB-Abfragebefehle für die Datenanalyse
MongoDB-Abfragen werden nützlicher, wenn Sie über einfache find()-Aufrufe hinausgehen. Wenn Sie verschachtelte Dokumente filtern, die Ausgabe umformen oder gruppierte Ergebnisse berechnen müssen, ermöglichen Ihnen erweiterte Abfrageoperatoren und Aggregationsstufen, diese Arbeit nahe an den Daten durchzuführen.
Die folgenden Beispiele konzentrieren sich auf praktische Befehle, die Sie in mongosh für Berichte, Fehlerbehebung und einmalige Analysen ausführen können.
Beherrschung komplexer Filterung mit Abfrageoperatoren
Während die grundlegende find()-Methode einfache Gleichheitsprüfungen handhabt, erfordert die erweiterte Analyse oft die Kombination mehrerer Bedingungen oder die Abfrage spezifischer Feldstrukturen. MongoDB bietet eine Vielzahl von Abfrageoperatoren, um granulare Filter zu erstellen.
Logische Operatoren für zusammengesetzte Abfragen
Logische Operatoren ermöglichen es Ihnen, mehrere Abfragebedingungen zu kombinieren und bieten eine fein abgestimmte Kontrolle darüber, welche Dokumente zurückgegeben werden. Diese sind für die Strukturierung komplexer analytischer Fragen unerlässlich.
$and/ Implizites$and: Wird verwendet, um mehrere Kriterien anzugeben, die alle wahr sein müssen. Während es oft implizit ist (Bedingungen nacheinander im Abfrageobjekt auflisten), ist$andnotwendig, wenn dasselbe Feld mehrmals abgefragt wird.// Implizites $and: Finde Benutzer älter als 25 UND die in New York leben db.users.find({ age: { $gt: 25 }, city: "New York" }); // Explizites $and: Finde Dokumente, bei denen 'score' > 90 ODER 'level' = 5 ist db.results.find({ $and: [ { score: { $gt: 90 } }, { level: 5 } ] });$or: Wählt Dokumente aus, die irgendeinem der angegebenen Array-Ausdrücke entsprechen.db.products.find({ $or: [ { category: "Electronics" }, { price: { $lt: 100 } } ] });$not: Negiert die Ergebnisse des angegebenen Ausdrucks.
Geodaten- und Array-Operatoren
Für standortbasierte Daten oder komplexe Arrays bieten spezialisierte Operatoren analytische Leistungsfähigkeit:
$geoWithin/$near: Unerlässlich zum Auffinden von Daten in einem bestimmten geografischen Gebiet oder in der Nähe.$elemMatch: Entscheidend für die Abfrage von Arrays eingebetteter Dokumente, um sicherzustellen, dass ein Element im Array allen angegebenen Kriterien innerhalb von$elemMatchentspricht.// Finde Bestellungen, bei denen mindestens ein Artikel im 'items'-Array über 500 kostet UND eine Menge größer als 1 hat db.orders.find({ items: { $elemMatch: { price: { $gt: 500 }, qty: { $gt: 1 } } } });
Erweiterte Projektion: Gestaltung der Ausgabe
Die Projektion, die mit dem zweiten Argument in der find()-Methode verwaltet wird, bestimmt, welche Felder zurückgegeben werden. Die erweiterte Projektion geht über einfaches Ein-/Ausschließen hinaus, um die zurückgegebenen Daten zu transformieren oder zu gestalten.
Feldausschluss und -einschluss
1schließt ein Feld ein;0schließt ein Feld aus.- Wichtiger Hinweis: Sie können Einschluss (
1) und Ausschluss (0) nicht mischen, außer für das Feld_id(das standardmäßig eingeschlossen ist und explizit ausgeschlossen werden kann, indem es auf0gesetzt wird).
// Nur 'name' und 'email' einschließen, '_id' ausschließen
db.users.find({}, { name: 1, email: 1, _id: 0 });
Array-Slicing und -Manipulation
Die Projektion kann die Anzahl der zurückgegebenen Array-Elemente mit $slice begrenzen:
$slice: N: Gibt die ersten N Elemente zurück.$slice: -N: Gibt die letzten N Elemente zurück.$slice: [M, N]: Gibt N Elemente ab Index M zurück.
// Nur die letzten 3 Einträge aus dem 'history'-Array zurückgeben
db.logs.find({}, { history: { $slice: -3 } });
Datenanalyse mit dem Aggregations-Framework
Das MongoDB-Aggregations-Framework ist das leistungsstärkste Werkzeug für komplexe Datenanalysen. Es ermöglicht die Verarbeitung von Datensätzen durch eine Pipeline von Stufen. Jede Stufe führt eine spezifische Transformation oder Operation an den von der vorherigen Stufe übergebenen Daten durch.
Wichtige Aggregationsstufen
Die grundlegende Struktur verwendet db.collection.aggregate([...pipeline]).
1. $match (Filterung)
Funktioniert ähnlich wie find(), wird aber vor nachfolgenden Stufen angewendet, was die Leistung optimiert, indem der Datensatz frühzeitig reduziert wird.
2. $group (Gruppierung und Berechnung)
Diese Stufe gruppiert Dokumente nach einer bestimmten Kennung (_id) und wendet Akkumulator-Operatoren an, um zusammenfassende Statistiken zu berechnen.
Häufige Akkumulatoren:
$sum$avg$min,$max$push(zum Sammeln von Array-Daten aus der Gruppe)
// Berechne die durchschnittliche Punktzahl pro Abteilung
db.scores.aggregate([
{ $group: {
_id: "$department",
averageScore: { $avg: "$score" },
totalStudents: { $sum: 1 }
} }
]);
3. $project (Umformung von Dokumenten)
Wird innerhalb der Aggregation verwendet, um die Ausgabedokumente umzuformen, ähnlich wie die find()-Projektion, aber oft verwendet, um neue berechnete Felder zu erstellen.
- Berechnete Felder: Sie können Berechnungen innerhalb der Projektionsstufe mit vorhandenen Feldern durchführen.
// Berechne die Gewinnspanne innerhalb der Pipeline
db.sales.aggregate([
{ $project: {
_id: 0,
productName: 1,
profit: { $subtract: ["$salePrice", "$cost"] }
} }
]);
4. $lookup (Verknüpfung von Daten)
Die $lookup-Stufe fügt passende Dokumente aus einer anderen Sammlung hinzu, ähnlich wie ein Left Outer Join. Sie ist nützlich, wenn Sie Dokumente für Berichte anreichern müssen, ohne den Join im Anwendungscode durchzuführen.
// Verknüpfung der 'orders'-Sammlung mit der 'customers'-Sammlung
db.orders.aggregate([
{ $match: { status: "Pending" } },
{ $lookup: {
from: "customers", // Sammlung, mit der verknüpft werden soll
localField: "customerId", // Feld aus den Eingabedokumenten (orders)
foreignField: "_id", // Feld aus den Dokumenten der "from"-Sammlung (customers)
as: "customerDetails" // Name des Ausgabearray-Felds
} }
]);
5. $unwind (Dekonstruktion von Arrays)
Wenn ein Array-Feld mehrere Elemente enthält, erstellt $unwind ein separates Ausgabedokument für jedes Element im Array, wodurch die Daten für eine einfachere Gruppierung oder Filterung von Array-Inhalten effektiv denormalisiert werden.
Warnung:
$unwindkann die Dokumentanzahl erheblich erhöhen. Verwenden Sie es mit Bedacht, typischerweise nach$match, um die Anfangsmenge zu reduzieren.
Best Practices für analytische Abfragen
- Indizieren Sie die Einstiegspunkte: Indizieren Sie Felder, die von frühen
$match-Stufen und indexgestützten$sort-Stufen verwendet werden.$groupkann von weniger Eingabedokumenten profitieren, wird aber nicht automatisch schnell, nur weil das gruppierte Feld einen Index hat. - Filtern Sie frühzeitig: Platzieren Sie
$match-Stufen so früh wie möglich in der Aggregations-Pipeline. Die frühzeitige Reduzierung der Dokumentanzahl spart erhebliche Rechenleistung für spätere, teurere Stufen wie$lookupoder$group. - Verwenden Sie geeignete Datentypen: Stellen Sie sicher, dass Vergleichsfelder (wie Daten oder numerische Werte) konsistent gespeichert werden. Typkonflikte führen dazu, dass
$match-Operatoren stillschweigend oder ineffizient fehlschlagen.
Verwenden Sie diese Befehle, wenn die einfache Datenabfrage nicht ausreicht. Beginnen Sie mit selektiven Filtern, projizieren Sie nur die benötigten Felder und wechseln Sie zur Aggregation, wenn Sie Gruppierung, Umformung oder Anreicherung von Sammlung zu Sammlung benötigen.