Kurs
Wenn du gerade mit MongoDB experimentierst, bist du wahrscheinlich an einen Punkt gekommen, an dem deine Dokumente etwas komplexer aussehen. Aus flachen, relational anmutenden Daten sind vielleicht verschachtelte Objekte, verschachtelte Arrays und womöglich vier oder fünf weitere Ebenen geworden. Wie fragst du diese Daten ab, wenn sie mehrere Ebenen tief liegen?
In diesem kurzen Tutorial schauen wir uns die Punktnotation in MongoDB an und wie wir damit Dokumente schnell und einfach nach Werten in verschachtelten Feldern filtern können.
Mit Punktnotation meinen wir die Trennung verschachtelter Felder durch einen Punkt als Trennzeichen. Zum Beispiel:
root_field.nested_field_1.next_layer_nested_field_1
Für jede Verschachtelungsebene fügen wir beim Abfragen einfach einen weiteren Punkt zwischen den Feldern ein. Im Lauf des Tutorials siehst du ausführlichere Beispiele.
Wenn du erst mit MongoDB startest, schau dir unbedingt DataCamps Introduction to MongoDB in Python course an.
Voraussetzungen
Damit dieses Tutorial für dich funktioniert, brauchst du eine bereitgestellte und konfigurierte MongoDB-Instanz. Heißt: Du solltest so weit sein, dass du MongoDB direkt nutzen kannst. Außerdem solltest du zumindest grundlegend mit Abfragen von Collections in MongoDB vertraut sein. Die Dokumentation ist ein guter Startpunkt, falls du Unterstützung brauchst.
Für dieses Beispiel nutzen wir die folgenden Daten in einer Datenbank „dbinc“ und einer Collection „people“:
[
{
"name": "Nic Raboy",
"websites": [
{
"type": "other",
"name": "Portfolio",
"url": "https://www.nraboy.com"
},
{
"type": "social",
"name": "LinkedIn",
"url": "https://www.linkedin.com/in/nraboy"
}
],
"employment": {
"employer": "MongoDB",
"address": {
"street": "1633 Broadway",
"city": "New York",
"state": "New York",
"postal_code": 10019
}
}
},
{
"name": "Tony Kim",
"websites": [
{
"type": "social",
"name": "LinkedIn",
"url": "https://www.linkedin.com/in/hyung-kim/"
},
{
"type": "coding",
"name": "GitHub",
"url": "https://github.com/hjkmines"
}
],
"employment": {
"employer": "MongoDB",
"address": {
"street": "1633 Broadway",
"city": "New York",
"state": "New York",
"postal_code": 10019
}
}
}
]
Die obigen Daten zeigen zwei Dokumente mit einiger Komplexität, da sie verschachtelte Objekte und Arrays enthalten. Fun Fact: MongoDB unterstützt in BSON-Dokumenten über 100 Ebenen der Verschachtelung.
Wenn du mitmachen möchtest, stelle sicher, dass diese Dokumente in deiner MongoDB-Instanz vorhanden sind.
Daten in MongoDB mit verschiedenen Ansätzen abfragen
Wir starten einfach und tasten uns Schritt für Schritt an komplexere Fälle heran. Die gute Nachricht: Komplex heißt hier nicht automatisch schwierig.
Angenommen, wir möchten alle Personen in unserer Collection finden, die bei MongoDB arbeiten. Wir könnten eine Abfrage wie die folgende ausführen:
use dbinc;
db.people.find({
"employment.employer": "MongoDB"
});
In diesem Beispiel ist employer ein verschachteltes Feld innerhalb des Objekts employment. Wir können dieses Feld per Punktnotation abfragen, also durch Felder, die mit Punkten getrennt sind. Das ist nicht anders, als wenn wir alle Personen finden möchten, die in New York arbeiten. Dann könnten wir Folgendes tun:
use dbinc;
db.people.find({
"employment.address.state": "New York"
});
In der obigen Abfrage sind wir drei Ebenen in das Dokument hinabgestiegen, und es funktioniert problemlos.
Als Nächstes schauen wir uns das verschachtelte Array von Objekten an. Je nach Ziel gibt es dafür mehrere Abfragewege.
Angenommen, wir möchten alle Personen zurückgeben, die eine Website „Portfolio“ eingetragen haben. Wir könnten folgende Abfrage ausführen:
use dbinc;
db.people.find({
"websites.name": "Portfolio"
});
Diese Abfrage liefert genau ein Ergebnis, weil nur eines der Dokumente ein „Portfolio“ enthält. Beachte: Obwohl es ein Array ist, funktioniert die Punktnotation weiterhin. Die Bedingung ist, dass „Portfolio“ mindestens einmal irgendwo im Array vorkommt.
Jetzt wird es interessant.
Nehmen wir an, wir wollen die zurückgegebenen Ergebnisse weiter einschränken. Wir würden zusätzliche Filterkriterien hinzufügen, doch bei verschachtelten Objekten in Arrays ist das etwas anders. Betrachte zum Beispiel Folgendes:
use dbinc;
db.people.find({
"websites.name": "Portfolio",
"websites.type": "social"
});
In diesem Beispiel fordern wir Ergebnisse, in denen sowohl „Portfolio“ als auch „social“ im Array vorkommen, aber nicht zwingend im selben Objekt. Wir bekommen nur ein Ergebnis zurück, weil das Dokument „Tony Kim“ zwar „social“, aber kein „Portfolio“ enthält. Wenn beide Felder im selben Array-Objekt vorhanden sein müssen, reicht die Punktnotation dafür nicht aus.
Auch wenn es den Rahmen dieses Tutorials sprengt: Mit dem Operator $elemMatch lässt sich das so lösen:
use dbinc;
db.people.find(
{
"websites": {
"$elemMatch": {
"name": "Portfolio",
"type": "social"
}
}
}
);
In diesem Fall würde kein Ergebnis zurückgegeben, weil unsere Beispieldaten kein passendes name und type im selben Objekt enthalten.
Wenn du mit Arrays arbeitest und den gewünschten Array-Index kennst, kannst du weiter Punktnotation verwenden. Zum Beispiel so:
use dbinc;
db.people.find({
"websites.0.name": "Portfolio"
});
Die Abfrage nutzt den Index des Arrays, gegen den du matchen möchtest. In diesem Szenario wollen wir alle Dokumente zurückgeben, bei denen das erste Element im Array einen name von „Portfolio“ hat.
Auch wenn es außerhalb des Tutorial-Umfangs liegt, ist wichtig zu erwähnen: Die Punktnotation ist nicht auf Leseabfragen beschränkt. Du kannst sie ebenso in Update-Operationen, Projektionen und Aggregation-Pipelines einsetzen.
Fazit
Du hast eine schnelle Einführung in die Punktnotation für MongoDB-Abfragen bekommen. Wir haben gelernt:
- Punktnotation funktioniert für verschachtelte Objekte.
- Du kannst Punktnotation bei Arrays nutzen, jedoch mit Einschränkungen je nach Erwartung an diese Arrays.
- Der Operator
$elemMatchist nötig, wenn du mehrere Felder innerhalb desselben Array-Objekts matchen willst. - Array-Indizes in der Punktnotation lassen sich nutzen, um gezielt Elemente eines Arrays abzufragen.
Die Daten in deinen MongoDB-Collections sind vermutlich nicht flach. Früher oder später arbeitest du mit verschachtelten Objekten, verschachtelten Arrays, Arrays in Objekten und jeder Menge Kombinationen. Die gute Nachricht: MongoDB macht die Arbeit damit dank der leistungsfähigen Query-API einfach.
Wenn du MongoDB noch nicht nutzt, schau dir MongoDB Atlas an oder mein anderes Tutorial zum Einstieg in MongoDB mit Docker. In unserem separaten Guide erfährst du außerdem mehr zur MongoDB Certification.
FAQs
Was ist die Punktnotation in MongoDB?
Die Punktnotation bezeichnet den Zugriff auf verschachtelte Felder eines MongoDB-Dokuments mithilfe eines Punktes als Trennzeichen.
Kann ich in meinen Abfragen mit mehreren verschachtelten Feldern filtern?
Ja, deine Match-Abfragen können die Punktnotation für alle, einige oder keine Felder verwenden. Es ist derselbe Filter—du greifst nur auf verschachtelte Elemente zu.
Was mache ich mit unvorhersehbaren Arrays?
Achte darauf, dass deine Arrays der Größe und Performance zuliebe nicht unendlich wachsen. Mit Punktnotation lassen sie sich dennoch problemlos und einfach abfragen.
Was, wenn ich ein Dokument mit verschachtelten Objekten und Arrays aktualisieren muss?
Bei Update-Operationen funktioniert die Punktnotation sowohl im Filterteil der Operation als auch im Änderungsteil.