- 1 Section
- 10 Lessons
- unbegrenzt
- NoSQL – MongoDB, Redis & Grundlagen10
MongoDB CRUD-Operationen
Nach den Konzepten aus Lektion 4 wird's praktisch. CRUD steht für Create, Read, Update, Delete – die vier Basis-Operationen jeder Datenbank. In MongoDB heißen die Befehle anders als in SQL, machen aber dasselbe: Daten einfügen, abfragen, ändern, löschen.
Das Besondere bei MongoDB: Query-Bedingungen und Updates sind selbst JSON-Objekte mit speziellen Operatoren. Statt einer eigenen Sprache wie SQL nutzt MongoDB einen Query-by-Example-Ansatz. Diese Lektion zeigt die Operatoren, häufigsten Patterns und eine Sandbox zum Üben.
1) Create – Daten einfügen
Zum Einfügen gibt es zwei Methoden: insertOne für ein einzelnes Dokument, insertMany für mehrere. MongoDB generiert automatisch eine ObjectId als _id, wenn keine angegeben wird. Die Collection muss vorher nicht existieren – sie wird beim ersten Insert automatisch angelegt.
db.users.insertOne({
name: "Anna Bauer",
email: "anna@beispiel.de",
alter: 28,
tags: ["premium", "newsletter"]
});
// → { acknowledged: true, insertedId: ObjectId("...") }
// Mehrere Dokumente auf einmal
db.users.insertMany([
{ name: "Tim", alter: 35 },
{ name: "Lisa", alter: 42 }
]);
2) Read – Daten abfragen mit find()
Die Lese-Operation heißt find(). Sie nimmt ein Filter-Objekt – die direkte Entsprechung zur SQL-WHERE-Klausel. Ein leeres Filter-Objekt liefert alle Dokumente. Mehrere Felder im Filter werden mit implizitem AND verknüpft.
db.users.find();
// Mit Filter (entspricht WHERE in SQL)
db.users.find({ stadt: "Berlin" });
// Mehrere Bedingungen (impliziter AND)
db.users.find({ stadt: "Berlin", alter: 28 });
// Projection: nur bestimmte Felder zurückgeben (wie SELECT spalte1, spalte2)
db.users.find({ stadt: "Berlin" }, { name: 1, email: 1 });
// findOne: nur das erste passende Dokument
db.users.findOne({ email: "anna@beispiel.de" });
// Sortieren + Limitieren + Skip
db.users.find().sort({ alter: -1 }).limit(10).skip(20);
Die Projection { name: 1, email: 1 } ist das Äquivalent zu SELECT name, email FROM …. Das _id-Feld ist immer dabei, außer du setzt es explizit auf 0. Mit sort({alter: -1}) sortierst du absteigend (analog zu ORDER BY alter DESC).
3) Query-Operatoren – die wichtigsten Vergleiche
Einfache Gleichheit ({feld: wert}) reicht oft nicht. MongoDB hat eine Reihe spezieller Operatoren mit dem Dollar-Präfix, die SQL-Vergleichsoperatoren entsprechen. Diese werden in „verschachtelten Objekten" angewendet: das Feld zeigt auf ein Objekt mit Operator als Schlüssel.
$eq ist Default und wird meist weggelassen.> und >= in SQL.< und <=.IN.{ alter: { $gte: 18, $lt: 65 } } = „zwischen 18 und 65". Innerhalb eines Felds wirken mehrere Operatoren mit implizitem AND. Für OR über verschiedene Felder hinweg ist $or mit Array nötig: { $or: [{a:1},{b:2}] }.4) Live Query Builder
Bau dir eine Abfrage zusammen und sieh, welche Dokumente die Filter durchlassen. Die Test-Daten sind eine kleine User-Collection mit acht Einträgen:
$eq weg: { stadt: "Berlin" } ist die Kurzform für { stadt: { $eq: "Berlin" } }. Im Builder zeige ich es explizit zur Klarheit. Die Operatoren mit den größten Stolperfallen sind $regex (Pattern-Performance!) und $in mit großen Listen.5) Update – mit $set, nicht ohne!
Updates sehen auf den ersten Blick ungewohnt aus, weil sie mit einem speziellen Update-Operator $set arbeiten. Das ist wichtig. Ohne $set würde MongoDB das gesamte Dokument ersetzen, statt nur einzelne Felder zu ändern. Dieser Fehler hat schon ganze Kundendatenbanken in zwei Feld-Dokumente verwandelt:
$set ersetzt das ganze Dokument. { _id, alter: 29 } als Update-Operand löscht Name, Email, Stadt etc. – nur alter bleibt übrig. Immer mit $set schreiben!
db.users.updateOne(
{ _id: "u1" },
{ $set: { alter: 29, stadt: "Berlin" } }
);
// Mehrere Dokumente auf einmal updaten
db.users.updateMany(
{ stadt: "Berlin" },
{ $set: { land: "Deutschland" } }
);
Weitere wichtige Update-Operatoren: $inc (atomar inkrementieren), $push/$pull (Array-Elemente hinzufügen/entfernen), $unset (Feld komplett löschen), $rename (Feld umbenennen). Hier die häufigsten Patterns:
db.products.updateOne({ _id: "p1" }, { $inc: { verkaeufe: 1 } });
// Element zu Array hinzufügen
db.users.updateOne({ _id: "u1" }, { $push: { tags: "vip" } });
// Element aus Array entfernen
db.users.updateOne({ _id: "u1" }, { $pull: { tags: "newsletter" } });
// Feld komplett aus Dokument entfernen
db.users.updateOne({ _id: "u1" }, { $unset: { telefon: "" } });
Besonders $inc ist wichtig: es ist atomar. Selbst bei vielen parallelen Inkrementierungen geht keine verloren – im Gegensatz zu „read-modify-write" auf Anwendungsseite, das das klassische Lost-Update-Problem haben kann.
6) Upsert – einfügen oder updaten
Ein praktisches Pattern: „falls existiert update, sonst insert". Genau das macht Upsert – als Option der Update-Methode. Spart einen Round-Trip und ist häufig bei Import-Skripten:
{ email: "anna@beispiel.de" },
{ $set: { name: "Anna Bauer", alter: 28 } },
{ upsert: true }
);
// Wenn User mit der Mail existiert: updaten.
// Wenn nicht: neu anlegen (mit den $set-Werten + dem Filter-Feld).
In SQL entspricht das einem INSERT … ON DUPLICATE KEY UPDATE oder MERGE – aber in MongoDB ist es einfacher zu nutzen.
7) Delete – Dokumente löschen
Löschen funktioniert analog – deleteOne für ein Dokument, deleteMany für mehrere. Der Filter funktioniert wie bei find. Vorsicht bei leeren Filtern: deleteMany({}) löscht alle Dokumente!
db.users.deleteOne({ email: "anna@beispiel.de" });
// Alle Dokumente löschen die matchen
db.users.deleteMany({ aktiv: false });
// Alle Dokumente einer Collection löschen (Vorsicht!)
db.users.deleteMany({ }); // behält Indexe und Collection
db.users.drop(); // löscht Collection komplett
In rechtlich aufbewahrungspflichtigen Daten ist Soft-Delete verbreitet: statt zu löschen ein Feld deleted_at setzen. Die Anwendung filtert dann beim Lesen alles mit gesetztem deleted_at aus. Behält Daten für Audit-Zwecke, lässt sie aus Sicht der App aber verschwinden.
8) Bulk-Operationen für Performance
Wenn du viele Operationen ausführen willst, ist es deutlich schneller, sie in einem Aufruf zu bündeln statt einzeln zu senden. Jede einzelne Operation hat einen Netzwerk-Round-Trip – 1000 separate Inserts können 1000-mal länger dauern als insertMany mit 1000 Elementen.
for (let u of users) db.users.insertOne(u); // langsam!
// Gut: alle auf einmal
db.users.insertMany(users);
// Mit gemischten Operationen: bulkWrite
db.users.bulkWrite([
{ insertOne: { document: { name: "Tom" } } },
{ updateOne: { filter: { _id: "u1" }, update: { $set: { x: 1 } } } },
{ deleteOne: { filter: { _id: "u9" } } }
]);
Bei Imports großer Datenmengen kann der Performance-Unterschied Faktor 50 und mehr sein. Genauso wichtig: in Transaktionen verpacken wenn die Operationen logisch zusammengehören.
Zusammenfassung
CRUD in MongoDB: Create mit insertOne/insertMany, Read mit find/findOne (plus sort, limit, skip, Projection), Update mit updateOne/updateMany – immer mit $set verwenden, sonst wird das ganze Dokument ersetzt! Delete mit deleteOne/deleteMany. Query-Operatoren: $eq, $ne, $gt/$gte, $lt/$lte, $in/$nin, $and/$or, $exists, $regex, $all/$size. Update-Operatoren: $set, $inc (atomar), $push/$pull (Arrays), $unset, $rename. Upsert als kombiniertes „insert oder update". Performance-Tipp: Bulk-Operationen (insertMany, bulkWrite) statt vieler Einzelaufrufe – Faktor-50-Speedup möglich. Komplexere Abfragen mit Gruppierung und Joins macht man mit der Aggregation Pipeline (Lektion 6).
