Menu

MongoDB mit Node.js: Treiber-Beispiele für find und insert

MongoDB nutzt du in Node.js mit dem offiziellen Treiber mongodb: Verbinde dich mit MongoClient und füge dann Dokumente in einer Collection ein, finde, ändere und lösche sie, alles mit async/await.

Diese Seite enthält ausführbare Editoren. Bearbeiten, ausführen und Ausgabe sofort sehen.

Um MongoDB aus Node.js zu nutzen, installierst du den offiziellen Treiber (npm install mongodb), verbindest dich mit new MongoClient(uri), wählst eine Datenbank mit client.db('name') und eine Collection mit db.collection('name'). Jede Operation (insertOne, find, updateOne, deleteOne) gibt ein Promise zurück, du wartest also mit await darauf. Dokumente gehen als einfache JavaScript-Objekte hinein und kommen so wieder heraus.

Es gibt [ 'Dune', 'Neuromancer', 'Hyperion' ] aus. Die Datenbank shop und die Collection books existierten vorher nicht: MongoDB legt sie beim ersten Einfügen an, und toArray() lädt jedes Dokument, auf das der find()-Cursor zeigt.

Dokumente mit Filtern und Projection finden

Ein Filter ist ein Objekt, das die gewünschten Dokumente beschreibt. Einfache Werte passen exakt; Operatoren wie $gt, $lt, $in und $regex kommen in ein verschachteltes Objekt. Die projection im zweiten Argument wählt, welche Felder zurückkommen.

recent enthält die beiden neuesten Bücher nach 1960, erst Hyperion, dann Neuromancer, nur mit title und year; findOne gibt den ersten Treffer zurück (oder null), und countDocuments zählt 2 Bücher, die 10 oder mehr kosten. Ändere $gt: 1960 in $gt: 1985, und nur Hyperion bleibt übrig.

Ändern und löschen

updateOne(filter, update) ändert das erste passende Dokument. Das Update nutzt Operatoren: $set ersetzt Felder, $inc addiert zu einer Zahl, $unset entfernt ein Feld und $push hängt an ein Array an. updateMany und deleteMany wirken auf jeden Treffer.

Das Update hat ein Dokument gefunden und geändert, Dune kostet jetzt also 10 bei 2 auf Lager, und nach dem Löschen des Buchs ohne Bestand bleibt 1 übrig. Ein Update muss Operatoren nutzen: Übergib { price: 10 } ohne $set, und der Treiber lehnt es ab (replaceOne ist der Aufruf, der ein ganzes Dokument ersetzt).

ObjectId und Indexe

Jedes Dokument bekommt eine _id; wenn du keine setzt, erzeugt der Treiber eine ObjectId. Um ein Dokument über eine ID zu finden, die als String ankommt (etwa aus einer URL), pack sie in new ObjectId(id). Ein Index macht ein Feld schnell durchsuchbar, und ein Unique-Index lässt MongoDB Duplikate ablehnen.

Eine ObjectId ist als String 24 Hex-Zeichen lang, und die Suche mit dem einfachen String findet nichts, deshalb gibt diese Zeile null aus. Das zweite Einfügen verletzt den Unique-Index und schlägt mit Code 11000 fehl, so erkennst du "E-Mail schon vergeben".

MongoDB in einer Express-API nutzen

Verbinde dich einmal beim Serverstart und teil die Collection; öffne nicht pro Anfrage eine neue Verbindung. Der Treiber hält einen Pool von Verbindungen und verwendet sie wieder.

GET /books liefert beide Bücher, jedes mit einer _id. Kopier eine ID in GET /books/<id>, um ein einzelnes Buch abzurufen, oder sende POST /books mit einem JSON-Body wie {"title": "Foundation", "year": 1951} und lass dir die Bücher noch einmal auflisten.

Eine echte App liest den Connection String aus process.env.MONGODB_URI, statt ihn in den Code zu schreiben.

Wenn du Schemas und Validierung über dem Treiber willst, umhüllt ihn Mongoose (npm install mongoose):

const Book = mongoose.model('Book', new mongoose.Schema({ title: String, year: Number }));
await Book.create({ title: 'Dune', year: 1965 });

Häufige Fehler

toArray() vergessen. find() gibt einen Cursor zurück, keine Dokumente. Loggst du ihn, siehst du ein Cursor-Objekt; ruf toArray() auf oder durchlauf ihn mit for await.

Bei jeder Anfrage neu verbinden. Jeder new MongoClient öffnet einen eigenen Pool. Erstell beim Start einen Client und verwende ihn überall.

Den Client in einem Skript nie schließen. Ein offener Client hält den Prozess am Leben, nachdem dein Code fertig ist. Ruf am Ende von Skripten await client.close() auf; ein Server hält ihn während seiner ganzen Laufzeit offen.

Häufig gestellte Fragen

Soll ich den Treiber mongodb oder Mongoose nehmen?

Der Treiber ist die offizielle, dünnere Schicht: Du arbeitest mit einfachen Objekten und der eigenen Abfragesprache von MongoDB. Mongoose setzt Schemas, Validierung und Modelle obendrauf, was hilft, wenn jedes Dokument geprüft werden soll. Beide sprechen mit derselben Datenbank, und Mongoose nutzt darunter den Treiber.

Muss ich zuerst eine Datenbank oder Collection anlegen?

Nein. MongoDB legt beide an, wenn du zum ersten Mal ein Dokument einfügst. client.db('shop') und db.collection('books') geben nur Handles zurück.

Wohin kommt der Connection String?

In eine Umgebungsvariable wie MONGODB_URI, gelesen mit process.env.MONGODB_URI. Der String einer gehosteten Datenbank enthält ein Passwort und darf deshalb nie ins Repository committet werden.

Warum findet find keine Dokumente, wenn ich nach der ID suche?

_id ist als ObjectId gespeichert, nicht als String, deshalb passt { _id: '65f1...' } auf nichts. Wandle sie zuerst um: { _id: new ObjectId(id) }.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

Los geht's