PHP Conference Japan 2024

MongoDB\Driver\BulkWrite 類別

(mongodb >=1.0.0)

簡介

MongoDB\Driver\BulkWrite 類別收集一個或多個應傳送到伺服器的寫入操作。新增任意數量的插入、更新和刪除操作後,可以透過 MongoDB\Driver\Manager::executeBulkWrite() 執行集合。

寫入操作可以是有序的(預設)或無序的。有序寫入操作會按照提供的順序發送到伺服器,以便依序執行。如果寫入失敗,任何剩餘的操作都將中止。無序操作以任意順序發送到伺服器,它們可能並行執行。所有操作嘗試完成後,才會回報發生的任何錯誤。

類別概要

final class MongoDB\Driver\BulkWrite implements Countable {
/* 方法 */
public __construct(?陣列 $options = null)
public count(): 整數
public delete(陣列|物件 $filter, ?陣列 $deleteOptions = null):
public insert(陣列|物件 $document): 混合
public update(陣列|物件 $filter, 陣列|物件 $newObj, ?陣列 $updateOptions = null):
}

範例

範例 #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://127.0.0.1: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();

// Check if the write concern could not be fulfilled
if ($writeConcernError = $result->getWriteConcernError()) {
printf("%s (%d): %s\n",
$writeConcernError->getMessage(),
$writeConcernError->getCode(),
var_export($writeConcernError->getInfo(), true)
);
}

// Check if any write operations did not complete at all
foreach ($result->getWriteErrors() as $writeError) {
printf("Operation#%d: %s (%d)\n",
$writeError->getIndex(),
$writeError->getMessage(),
$writeError->getCode()
);
}
} catch (
MongoDB\Driver\Exception\Exception $e) {
printf("Other error: %s\n", $e->getMessage());
exit;
}

printf("Inserted %d document(s)\n", $result->getInsertedCount());
printf("Updated %d document(s)\n", $result->getModifiedCount());

?>

上述範例將會輸出

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

如果寫入條件無法滿足,上述範例將會輸出類似以下的內容

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)

目錄

新增註記

使用者貢獻的註記

此頁面沒有使用者貢獻的註記。
To Top