PHPCon Poland 2024

Класс MongoDB\Driver\BulkWrite

(mongodb >=1.0.0)

Введение

Класс MongoDB\Driver\BulkWrite собирает одну или несколько операций записи, которые должны быть отправлены на сервер. После добавления любого количества операций вставки, обновления или удаления, коллекция может быть выполнена с помощью MongoDB\Driver\Manager::executeBulkWrite().

Операции записи могут быть отсортированы (по умолчанию) или не отсортированы. Отсортированные операции записи отправляются на сервер в указанном порядке для последовательного выполнения. В случае возникновения ошибки записи, любые оставшиеся операции будут прерваны. Неотсортированные операции отправляются на сервер в произвольном порядке, где они могут выполняться параллельно. Сообщения об ошибках, которые возникают, будут отправлены после выполнения всех операций.

Обзор классов

final class MongoDB\Driver\BulkWrite implements Countable {
/* Методы */
public __construct(?array $options = null)
public count(): int
public delete(array|object $filter, ?array $deleteOptions = null): void
public insert(array|object $document): mixed
public update(array|object $filter, array|object $newObj, ?array $updateOptions = null): void
}

Примеры

Пример #1 Смешанные операции группируются по типу

Смешанные операции записи (т.е. добавления, обновления или удаления) будут собраны в типизированные команды записи, которые в последовательном порядке будут отправлены на сервер.

<?php

$bulk
= new MongoDB\Driver\BulkWrite(['ordered' => true]);
$bulk->insert(['_id' => 1, 'x' => 1]);
$bulk->insert(['_id' => 2, 'x' => 2]);
$bulk->update(['x' => 2], ['$set' => ['x' => 1]]);
$bulk->insert(['_id' => 3, 'x' => 3]);
$bulk->delete(['x' => 1]);

?>

В результате будут выполнены четыре команды записи (т.е. обращений). Поскольку операции отсортированы, третья вставка не может быть отправлена до тех пор, пока не будет выполнено предыдущее обновление.

Пример #2 Отсортированные операции записи, вызывающие ошибку

<?php

$bulk
= new MongoDB\Driver\BulkWrite(['ordered' => true]);
$bulk->delete([]);
$bulk->insert(['_id' => 1]);
$bulk->insert(['_id' => 2]);
$bulk->insert(['_id' => 3, 'hello' => 'world']);
$bulk->update(['_id' => 3], ['$set' => ['hello' => 'earth']]);
$bulk->insert(['_id' => 4, 'hello' => 'pluto']);
$bulk->update(['_id' => 4], ['$set' => ['hello' => 'moon']]);
$bulk->insert(['_id' => 3]);
$bulk->insert(['_id' => 4]);
$bulk->insert(['_id' => 5]);

$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
$writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000);

try {
$result = $manager->executeBulkWrite('db.collection', $bulk, $writeConcern);
} catch (
MongoDB\Driver\Exception\BulkWriteException $e) {
$result = $e->getWriteResult();

// Убедиться, что гарантия записи не может быть выполнена
if ($writeConcernError = $result->getWriteConcernError()) {
printf("%s (%d): %s\n",
$writeConcernError->getMessage(),
$writeConcernError->getCode(),
var_export($writeConcernError->getInfo(), true)
);
}

// Проверить, не выполнялись ли какие-либо операции записи
foreach ($result->getWriteErrors() as $writeError) {
printf("Operation#%d: %s (%d)\n",
$writeError->getIndex(),
$writeError->getMessage(),
$writeError->getCode()
);
}
} catch (
MongoDB\Driver\Exception\Exception $e) {
printf("Другая ошибка: %s\n", $e->getMessage());
exit;
}

printf("Добавлено %d документ(ов)\n", $result->getInsertedCount());
printf("Обновлено %d документ(ов)\n", $result->getModifiedCount());

?>

Результат выполнения приведённого примера:

Operation#7: E11000 duplicate key error index: db.collection.$_id_ dup key: { : 3 } (11000)
Добавлено 4 документ(ов)
Обновлено 2 документ(ов)

Если гарантия записи не может быть выполнена, результат вышеприведённого примера будет что-то вроде этого:

waiting for replication timed out (64): array (
  'wtimeout' => true,
)
Operation#7: E11000 duplicate key error index: databaseName.collectionName.$_id_ dup key: { : 3 } (11000)
Inserted 4 document(s)
Updated  2 document(s)

Если мы выполним пример выше, но разрешим неотсортированные записи:

<?php

$bulk
= new MongoDB\Driver\BulkWrite(['ordered' => false]);
/* ... */

?>

Результат выполнения приведённого примера:

Operation#7: E11000 duplicate key error index: db.collection.$_id_ dup key: { : 3 } (11000)
Operation#8: E11000 duplicate key error index: db.collection.$_id_ dup key: { : 4 } (11000)
Inserted 5 document(s)
Updated  2 document(s)

Содержание

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top