🍃 MongoDB mit PHP

Lernunterstützung für MongoDB und PHP © M. Meili

📚 Wichtige Informationen zum Thema XAMPP

1. Verbindung zur MongoDB herstellen

Grundlegende Verbindung
<?php // Lädt den Autoloader von Composer, der für die MongoDB-Bibliothek benötigt wird require 'vendor/autoload.php'; // Erstellt eine neue Verbindung zum MongoDB-Server auf localhost:27017 $client = new MongoDB\Client("mongodb://localhost:27017"); echo "Verbindung erfolgreich!"; ?>
Dies ist die Standard-Verbindung zu MongoDB. Der Autoloader wird benötigt, um die MongoDB-Library zu laden.
Datenbank und Collection auswählen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); // Datenbank auswählen $database = $client->schule; // Collection (Tabelle) auswählen $collection = $database->schueler; echo "Database: schule, Collection: schueler"; ?>
Collections sind wie Tabellen in SQL. Sie werden automatisch erstellt, wenn du das erste Dokument einfügst.

2. Create - Dokumente einfügen

Ein Dokument einfügen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Ein Dokument erstellen $dokument = [ "name" => "Anna Müller", "alter" => 15, "klasse" => "9a", "noten" => [2, 1, 3, 2] ]; // Dokument einfügen $result = $collection->insertOne($dokument); echo "Dokument eingefügt mit ID: " . $result->getInsertedId(); ?>
insertOne() fügt ein einzelnes Dokument ein. MongoDB erstellt automatisch eine eindeutige _id.
Mehrere Dokumente auf einmal einfügen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Mehrere Dokumente erstellen $dokumente = [ ["name" => "Max Weber", "alter" => 16, "klasse" => "10b"], ["name" => "Lisa Schmidt", "alter" => 15, "klasse" => "9a"], ["name" => "Tom Klein", "alter" => 17, "klasse" => "11c"] ]; // Alle Dokumente auf einmal einfügen $result = $collection->insertMany($dokumente); echo "Anzahl eingefügte Dokumente: " . $result->getInsertedCount(); ?>
insertMany() ist effizienter, wenn du mehrere Dokumente gleichzeitig einfügen möchtest.
Dokument mit eigener ID einfügen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Dokument mit eigener _id $dokument = [ "_id" => 12345, "name" => "Sophie Wagner", "alter" => 16 ]; $collection->insertOne($dokument); echo "Dokument mit eigener ID eingefügt!"; ?>
Du kannst auch eine eigene _id festlegen (muss aber eindeutig sein!).

3. Read - Dokumente anzeigen

Alle Dokumente anzeigen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Dokumente holen $dokumente = $collection->find(); // Durch alle Dokumente iterieren foreach ($dokumente as $dok) { echo "Name: " . $dok['name'] . ", Alter: " . $dok['alter'] . "<br>"; } ?>
Name: Anna Müller, Alter: 15 Name: Max Weber, Alter: 16 Name: Lisa Schmidt, Alter: 15
find() ohne Parameter gibt alle Dokumente zurück. Das Ergebnis ist iterierbar (foreach).
Ein einzelnes Dokument finden
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Ein Dokument finden $dokument = $collection->findOne(["name" => "Anna Müller"]); if ($dokument) { echo "Gefunden: " . $dokument['name'] . ", Klasse: " . $dokument['klasse']; } ?>
Gefunden: Anna Müller, Klasse: 9a
findOne() gibt nur das erste passende Dokument zurück (oder null, wenn nichts gefunden wurde).
Dokumente als Array konvertieren
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Dokumente als Array holen $dokumente = $collection->find()->toArray(); // Anzahl anzeigen echo "Anzahl Schüler: " . count($dokumente); // Alle ausgeben print_r($dokumente); ?>
Mit toArray() kannst du alle Ergebnisse auf einmal in ein PHP-Array umwandeln.
Anzahl Dokumente zählen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Dokumente zählen $anzahl = $collection->countDocuments(); echo "Gesamt: " . $anzahl . " Schüler<br>"; // Mit Filter zählen $anzahl_9a = $collection->countDocuments(["klasse" => "9a"]); echo "Klasse 9a: " . $anzahl_9a . " Schüler"; ?>
Gesamt: 4 Schüler Klasse 9a: 2 Schüler
countDocuments() zählt Dokumente, optional mit Filter.

4. Filter und Queries

Einfache Filter
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Schüler aus Klasse 9a $dokumente = $collection->find(["klasse" => "9a"]); foreach ($dokumente as $dok) { echo $dok['name'] . "<br>"; } ?>
Filter werden als assoziative Arrays übergeben. Alle Bedingungen müssen erfüllt sein (AND).
Vergleichsoperatoren ($gt, $lt, $gte, $lte)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Schüler älter als 15 $dokumente = $collection->find([ "alter" => ['$gt' => 15] ]); // Schüler zwischen 15 und 17 Jahren $dokumente2 = $collection->find([ "alter" => [ '$gte' => 15, '$lte' => 17 ] ]); ?>
$gt = greater than (grösser als), $gte = greater than or equal (grösser oder gleich), $lt = less than, $lte = less than or equal
IN-Operator für mehrere Werte
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Schüler aus Klasse 9a ODER 10b $dokumente = $collection->find([ "klasse" => ['$in' => ["9a", "10b", "11c"]] ]); foreach ($dokumente as $dok) { echo $dok['name'] . " - " . $dok['klasse'] . "<br>"; } ?>
$in sucht nach Dokumenten, die einen der angegebenen Werte haben (wie SQL IN).
UND/ODER-Verknüpfungen ($and, $or)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Schüler aus 9a ODER älter als 16 $dokumente = $collection->find([ '$or' => [ ["klasse" => "9a"], ["alter" => ['$gt' => 16]] ] ]); // Schüler aus 9a UND älter als 14 $dokumente2 = $collection->find([ '$and' => [ ["klasse" => "9a"], ["alter" => ['$gt' => 14]] ] ]); ?>
Mit $or und $and kannst du komplexe Bedingungen erstellen.
Textsuche mit Regex
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Namen die "Anna" enthalten (case-insensitive) $dokumente = $collection->find([ "name" => new MongoDB\BSON\Regex("Anna", "i") ]); foreach ($dokumente as $dok) { echo $dok['name'] . "<br>"; } ?>
Mit Regex kannst du Muster in Texten suchen. "i" bedeutet case-insensitive (Gross-/Kleinschreibung egal).

5. Update - Dokumente aktualisieren

Ein Dokument aktualisieren
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Ein Feld aktualisieren $result = $collection->updateOne( ["name" => "Anna Müller"], ['$set' => ["alter" => 16]] ); echo "Aktualisiert: " . $result->getModifiedCount() . " Dokument(e)"; ?>
updateOne() aktualisiert das erste passende Dokument. $set setzt/aktualisiert Felder.
Mehrere Dokumente aktualisieren
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Schüler aus 9a auf 10a setzen $result = $collection->updateMany( ["klasse" => "9a"], ['$set' => ["klasse" => "10a"]] ); echo "Aktualisiert: " . $result->getModifiedCount() . " Dokument(e)"; ?>
updateMany() aktualisiert alle passenden Dokumente.
Feld hinzufügen oder entfernen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Neues Feld hinzufügen $collection->updateOne( ["name" => "Anna Müller"], ['$set' => ["email" => "anna@schule.de"]] ); // Feld entfernen $collection->updateOne( ["name" => "Anna Müller"], ['$unset' => ["email" => ""]] ); ?>
$set fügt neue Felder hinzu, $unset entfernt Felder komplett.
Zahlen inkrementieren ($inc)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alter um 1 erhöhen $collection->updateOne( ["name" => "Anna Müller"], ['$inc' => ["alter" => 1]] ); // Oder um 2 verringern $collection->updateOne( ["name" => "Tom Klein"], ['$inc' => ["alter" => -2]] ); ?>
$inc erhöht/verringert Zahlenwerte ohne den aktuellen Wert auslesen zu müssen.
Arrays bearbeiten ($push, $pull)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Element zum Array hinzufügen $collection->updateOne( ["name" => "Anna Müller"], ['$push' => ["noten" => 1]] ); // Element aus Array entfernen $collection->updateOne( ["name" => "Anna Müller"], ['$pull' => ["noten" => 3]] ); ?>
$push fügt Elemente zu Arrays hinzu, $pull entfernt sie.
Upsert - Update oder Insert
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Wenn nicht vorhanden, dann einfügen $result = $collection->updateOne( ["name" => "Sarah Becker"], ['$set' => ["alter" => 15, "klasse" => "9b"]], ['upsert' => true] ); if ($result->getUpsertedCount() > 0) { echo "Neues Dokument eingefügt!"; } ?>
Mit upsert=true wird ein Dokument eingefügt, wenn es nicht existiert. Sehr praktisch!

6. Delete - Dokumente löschen

Ein Dokument löschen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Ein Dokument löschen $result = $collection->deleteOne(["name" => "Anna Müller"]); echo "Gelöscht: " . $result->getDeletedCount() . " Dokument(e)"; ?>
deleteOne() löscht das erste passende Dokument.
Mehrere Dokumente löschen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Schüler aus Klasse 9a löschen $result = $collection->deleteMany(["klasse" => "9a"]); echo "Gelöscht: " . $result->getDeletedCount() . " Dokument(e)"; ?>
deleteMany() löscht alle passenden Dokumente.
Alle Dokumente aus Collection löschen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // VORSICHT: Löscht ALLE Dokumente! $result = $collection->deleteMany([]); echo "Alle Dokumente gelöscht: " . $result->getDeletedCount(); ?>
⚠️ VORSICHT: Ein leeres Array [] als Filter löscht ALLE Dokumente in der Collection!
Collection komplett löschen (DROP)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Collection komplett entfernen $collection->drop(); echo "Collection 'schueler' wurde komplett gelöscht!"; ?>
⚠️ drop() löscht die gesamte Collection mit allen Dokumenten und Indizes!

7. Sortierung

Aufsteigend sortieren
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Nach Alter sortieren (aufsteigend) $dokumente = $collection->find( [], ['sort' => ['alter' => 1]] ); foreach ($dokumente as $dok) { echo $dok['name'] . " - " . $dok['alter'] . "<br>"; } ?>
1 = aufsteigend (ascending), von klein nach gross
Absteigend sortieren
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Nach Alter sortieren (absteigend) $dokumente = $collection->find( [], ['sort' => ['alter' => -1]] ); foreach ($dokumente as $dok) { echo $dok['name'] . " - " . $dok['alter'] . "<br>"; } ?>
-1 = absteigend (descending), von gross nach klein
Nach mehreren Feldern sortieren
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Erst nach Klasse, dann nach Name sortieren $dokumente = $collection->find( [], ['sort' => [ 'klasse' => 1, 'name' => 1 ]] ); ?>
Du kannst nach mehreren Feldern sortieren. Die Reihenfolge im Array bestimmt die Priorität.

8. Limit und Skip (Pagination)

Anzahl begrenzen (Limit)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Nur die ersten 3 Dokumente $dokumente = $collection->find( [], ['limit' => 3] ); foreach ($dokumente as $dok) { echo $dok['name'] . "<br>"; } ?>
limit begrenzt die Anzahl der zurückgegebenen Dokumente.
Dokumente überspringen (Skip)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Überspringe die ersten 2 Dokumente $dokumente = $collection->find( [], ['skip' => 2] ); foreach ($dokumente as $dok) { echo $dok['name'] . "<br>"; } ?>
skip überspringt die angegebene Anzahl von Dokumenten am Anfang.
Pagination (Seiten blättern)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Pagination Parameter $seite = 2; // Aktuelle Seite $pro_seite = 5; // Dokumente pro Seite $skip = ($seite - 1) * $pro_seite; // Seite 2 holen (Dokumente 6-10) $dokumente = $collection->find( [], [ 'skip' => $skip, 'limit' => $pro_seite, 'sort' => ['name' => 1] ] ); foreach ($dokumente as $dok) { echo $dok['name'] . "<br>"; } ?>
Kombiniere skip und limit für Pagination. Vergiss nicht zu sortieren für konsistente Ergebnisse!

9. Felder auswählen (Projection)

Nur bestimmte Felder zurückgeben
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Nur Name und Klasse ausgeben (ohne _id) $dokumente = $collection->find( [], ['projection' => [ 'name' => 1, 'klasse' => 1, '_id' => 0 ]] ); foreach ($dokumente as $dok) { print_r($dok); } ?>
1 = Feld einschliessen, 0 = Feld ausschliessen. Die _id ist standardmässig dabei, ausser du schliesst sie explizit aus.
Felder ausschliessen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Felder AUSSER noten $dokumente = $collection->find( [], ['projection' => [ 'noten' => 0 ]] ); ?>
Du kannst entweder Felder ein- ODER ausschliessen (nicht mischen, ausser bei _id).

10. Aggregation Pipeline

Einfache Gruppierung
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Anzahl Schüler pro Klasse $result = $collection->aggregate([ ['$group' => [ '_id' => '$klasse', 'anzahl' => ['$sum' => 1] ]] ]); foreach ($result as $doc) { echo "Klasse " . $doc['_id'] . ": " . $doc['anzahl'] . " Schüler<br>"; } ?>
Aggregation ist mächtig für Berechnungen und Gruppierungen. $group fasst Dokumente zusammen.
Durchschnitt berechnen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Durchschnittsalter pro Klasse $result = $collection->aggregate([ ['$group' => [ '_id' => '$klasse', 'durchschnittsalter' => ['$avg' => '$alter'] ]] ]); foreach ($result as $doc) { echo "Klasse " . $doc['_id'] . ": Ø " . round($doc['durchschnittsalter'], 1) . " Jahre<br>"; } ?>
$avg berechnet den Durchschnitt eines Feldes.
Match und Sort in Pipeline
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Schüler über 15, gruppiert und sortiert $result = $collection->aggregate([ ['$match' => ['alter' => ['$gt' => 15]]], ['$group' => [ '_id' => '$klasse', 'anzahl' => ['$sum' => 1] ]], ['$sort' => ['anzahl' => -1]] ]); ?>
Die Pipeline durchläuft mehrere Stufen: $match filtert, $group gruppiert, $sort sortiert.

11. Indexe für Performance

Einfachen Index erstellen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Index auf 'name' Feld erstellen $collection->createIndex(['name' => 1]); echo "Index auf 'name' erstellt!"; ?>
Indexe beschleunigen Abfragen erheblich, besonders bei grossen Collections!
Zusammengesetzten Index erstellen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Index auf mehreren Feldern $collection->createIndex([ 'klasse' => 1, 'alter' => -1 ]); echo "Zusammengesetzter Index erstellt!"; ?>
Zusammengesetzte Indexe sind nützlich für Queries auf mehreren Feldern.
Alle Indexe anzeigen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Alle Indexe auflisten foreach ($collection->listIndexes() as $index) { print_r($index); } ?>
Mit listIndexes() siehst du alle vorhandenen Indexe.
Index löschen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; // Index löschen $collection->dropIndex('name_1'); echo "Index gelöscht!"; ?>
Der Index-Name ist normalerweise feldname_1 oder feldname_-1.

12. Fehlerbehandlung

Try-Catch für Verbindungsfehler
<?php require 'vendor/autoload.php'; try { $client = new MongoDB\Client("mongodb://localhost:27017"); // Verbindung testen $client->listDatabases(); echo "Verbindung erfolgreich!"; } catch (MongoDB\Driver\Exception\Exception $e) { echo "Fehler: " . $e->getMessage(); } ?>
Fange immer Exceptions ab, um saubere Fehlerbehandlung zu haben!
Fehlerbehandlung bei Operationen
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; try { // Versuche einzufügen $collection->insertOne([ "_id" => 1, "name" => "Test" ]); echo "Dokument eingefügt!"; } catch (MongoDB\Driver\Exception\BulkWriteException $e) { echo "Fehler beim Einfügen: " . $e->getMessage(); // Z.B. wenn _id bereits existiert } ?>
BulkWriteException wird bei Insert/Update/Delete-Fehlern geworfen.

13. Vollständiges CRUD-Beispiel mit GUI

HTML-Formular zum Einfügen
<!DOCTYPE html> <html> <body> <h2>Neuen Schüler hinzufügen</h2> <form method="POST" action="einfuegen.php"> Name: <input type="text" name="name" required><br> Alter: <input type="number" name="alter" required><br> Klasse: <input type="text" name="klasse" required><br> <button type="submit">Hinzufügen</button> </form> </body> </html>
PHP-Script zum Verarbeiten (einfuegen.php)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; if ($_SERVER['REQUEST_METHOD'] == 'POST') { $dokument = [ "name" => $_POST['name'], "alter" => (int)$_POST['alter'], "klasse" => $_POST['klasse'] ]; $collection->insertOne($dokument); echo "Schüler erfolgreich hinzugefügt!"; echo "<br><a href='anzeigen.php'>Alle anzeigen</a>"; } ?>
Alle Dokumente mit HTML-Tabelle anzeigen (anzeigen.php)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; $dokumente = $collection->find(); ?> <h2>Alle Schüler</h2> <table border="1"> <tr> <th>Name</th> <th>Alter</th> <th>Klasse</th> <th>Aktionen</th> </tr> <?php foreach ($dokumente as $dok): ?> <tr> <td><?= $dok['name'] ?></td> <td><?= $dok['alter'] ?></td> <td><?= $dok['klasse'] ?></td> <td> <a href="loeschen.php?id=<?= $dok['_id'] ?>">Löschen</a> </td> </tr> <?php endforeach; ?> </table>
Dies ist ein einfaches Beispiel einer HTML-Tabelle mit allen Schülern und Lösch-Link.
Dokument löschen (loeschen.php)
<?php require 'vendor/autoload.php'; $client = new MongoDB\Client("mongodb://localhost:27017"); $collection = $client->schule->schueler; if (isset($_GET['id'])) { // ID von String zu ObjectId konvertieren $id = new MongoDB\BSON\ObjectId($_GET['id']); $collection->deleteOne(['_id' => $id]); echo "Schüler gelöscht!"; echo "<br><a href='anzeigen.php'>Zurück zur Liste</a>"; } ?>
Wichtig: Die _id muss als ObjectId-Objekt konvertiert werden!

14. Tipps und Best Practices

✅ Wichtige Tipps
1. Verbindung wiederverwenden: Erstelle die $client-Verbindung nur einmal und verwende sie mehrfach.

2. Indexe nutzen: Erstelle Indexe auf häufig gesuchten Feldern für bessere Performance.

3. Projection verwenden: Hole nur die Felder, die du wirklich brauchst.

4. Try-Catch benutzen: Fange immer Exceptions ab für saubere Fehlerbehandlung.

5. ObjectId konvertieren: Wenn du mit _id arbeitest, konvertiere Strings zu ObjectId.

6. Prepared Updates: Nutze $set, $inc, etc. statt das ganze Dokument zu ersetzen.

7. Validierung: Validiere User-Input bevor du ihn in MongoDB speicherst.

8. Limit nutzen: Verwende limit() bei grossen Datenmengen, um Speicher zu sparen.
❌ Häufige Fehler vermeiden
Fehler 1: vendor/autoload.php vergessen → Lösung: Immer require 'vendor/autoload.php'; am Anfang

Fehler 2: _id als String übergeben → Lösung: new MongoDB\BSON\ObjectId($id)

Fehler 3: Kein try-catch → Lösung: Immer Exceptions abfangen

Fehler 4: Dokument ohne $set updaten → Lösung: Immer ['$set' => [...]] verwenden

Fehler 5: Keine Indexe → Lösung: Indexe auf oft gesuchte Felder erstellen