Signatur
Beschreibung
MongoDB\Driver\BulkWrite ermöglicht es, mehrere Schreiboperationen (Einfügen, Aktualisieren, Löschen) zu bündeln und in einem einzigen Netzwerk-Roundtrip an den MongoDB-Server zu senden. Dadurch wird die Performance im Vergleich zu einzelnen Operationen erheblich verbessert, insbesondere wenn viele Datensätze gleichzeitig bearbeitet werden müssen.
Ein BulkWrite-Objekt wird zunächst durch Aufrufe der Methoden insert(), update() und delete() befüllt und anschließend über MongoDB\Driver\Manager::executeBulkWrite() ausgeführt. Das Ergebnis der Ausführung ist ein MongoDB\Driver\WriteResult-Objekt.
Standardmäßig werden Operationen in der Reihenfolge ausgeführt, in der sie hinzugefügt wurden (ordered). Im geordneten Modus bricht MongoDB die Verarbeitung beim ersten Fehler ab. Im ungeordneten Modus ('ordered' => false) werden alle Operationen unabhängig voneinander ausgeführt, und Fehler werden am Ende gesammelt gemeldet.
Die Klasse ist besonders nützlich bei Massen-Importen, Migrations-Skripten oder bei der Verarbeitung großer Datensätze, bei denen minimaler Netzwerk-Overhead entscheidend ist.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $options | array | [] | Optionales assoziatives Array. Unterstützt den Schlüssel ordered (bool, Standard: true): Bei true werden Operationen sequenziell ausgeführt und bei Fehler abgebrochen; bei false laufen alle Operationen unabhängig durch. |
Rückgabewert
Beispiele
Geordnetes BulkWrite: Insert, Update und Delete kombinieren
<?php
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => true]);
// Dokument einfügen
$id1 = $bulk->insert(['name' => 'Alice', 'age' => 30]);
$id2 = $bulk->insert(['name' => 'Bob', 'age' => 25]);
// Dokument aktualisieren (upsert)
$bulk->update(
['name' => 'Alice'],
['$set' => ['age' => 31]],
['multi' => false, 'upsert' => false]
);
// Dokument löschen
$bulk->delete(['name' => 'Bob'], ['limit' => 1]);
try {
$result = $manager->executeBulkWrite('testdb.users', $bulk);
echo 'Eingefügt: ' . $result->getInsertedCount() . PHP_EOL;
echo 'Aktualisiert: ' . $result->getModifiedCount() . PHP_EOL;
echo 'Gelöscht: ' . $result->getDeletedCount() . PHP_EOL;
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
echo 'Fehler: ' . $e->getMessage() . PHP_EOL;
}
Ungeordnetes BulkWrite für Massenimport
<?php
$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$datensaetze = [
['sku' => 'A001', 'preis' => 9.99, 'lager' => 100],
['sku' => 'A002', 'preis' => 14.99, 'lager' => 50],
['sku' => 'A003', 'preis' => 4.49, 'lager' => 200],
];
// Ungeordnet: alle Operationen werden versucht, auch wenn einzelne fehlschlagen
$bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]);
foreach ($datensaetze as $datensatz) {
$bulk->update(
['sku' => $datensatz['sku']],
['$set' => $datensatz],
['upsert' => true]
);
}
try {
$result = $manager->executeBulkWrite('shop.produkte', $bulk);
echo 'Upserts: ' . $result->getUpsertedCount() . PHP_EOL;
echo 'Aktualisiert: ' . $result->getModifiedCount() . PHP_EOL;
} catch (MongoDB\Driver\Exception\BulkWriteException $e) {
$writeResult = $e->getWriteResult();
echo 'Teilweise ausgeführt. Fehler: ' . $e->getMessage() . PHP_EOL;
echo 'Erfolgreich upserted: ' . $writeResult->getUpsertedCount() . PHP_EOL;
}
// Wichtig · Fallstricke
Fehlerbehandlung: Bei geordneten Bulk-Writes wirft executeBulkWrite() eine MongoDB\Driver\Exception\BulkWriteException, sobald die erste Operation fehlschlägt. Über $e->getWriteResult() lassen sich trotzdem Informationen zu bereits erfolgreich ausgeführten Operationen abrufen.
Dokumenten-IDs: Die Methode insert() gibt die generierte _id des Dokuments zurück (als MongoDB\BSON\ObjectId oder den übergebenen Wert). Wird keine _id im Dokument angegeben, generiert der Treiber automatisch eine ObjectId.
Größenbeschränkung: MongoDB begrenzt die maximale Größe eines BulkWrite-Batches auf 100.000 Operationen oder 48 MB. Der PHP-Treiber teilt größere Batches automatisch auf.
Wiederverwendung: Ein BulkWrite-Objekt kann nach executeBulkWrite() nicht erneut ausgeführt werden. Für weitere Operationen muss ein neues Objekt erstellt werden.