Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Docs 菜单
Docs 主页
/ / /
PHP 库手册
/

批量写入操作

在本指南中,您可以学习;了解如何使用批量写入操作在单个数据库调用中执行多个写入操作。

考虑这样一个场景:您要插入一个文档,更新多个其他文档,然后删除一个文档。 如果使用单独的方法,则每个操作都需要调用自己的数据库。

通过使用批量写入操作,您可以通过更少的数据库调用来执行多个写入操作。 您可以在以下级别执行批量写入操作:

  • 客户端:如果您的应用程序连接到MongoDB Server 8.0 或更高版本,则可以使用 MongoDB\Client::bulkWrite() 方法对同一集群中的多个集合和数据库执行批量写入操作。此方法在一次数据库调用中执行所有写入操作。要学习;了解有关此功能的更多信息,请参阅 Mongo.bulkWrite()MongoDB Server手册中的参考文档。

  • 集合:您可以使用 MongoDB\Collection::bulkWrite() 方法对单个集合执行批量写入操作。此方法对每种类型的写入操作进行一次数据库调用。示例,该方法可以在一次调用中执行多个更新操作,但会两次单独调用数据库以执行插入操作和替换操作。

本指南中的示例使用Atlas示例数据集中的sample_restaurants.restaurantssample_mflix.movies 集合。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅Atlas入门指南。

使用PHP库 v2.1 并连接到运行MongoDB Server 8.0 或更高版本的部署时,可以使用 MongoDB\Client::bulkWrite() 方法写入同一集群中的多个数据库和集合。此方法在一次调用中执行所有写入操作。

首先,使用 MongoDB\ClientBulkWrite 构建器创建BulkWriteCommand实例,以指定要执行的写入操作。以下代码演示了如何使用 createWithCollection() 方法从 MongoDB\Collection实例创建 ClientBulkWrite实例:

$restaurantCollection = $client->sample_restaurants->restaurants;
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);

然后,在 ClientBulkWrite实例上调用以下一个或多个写入方法以构造批量写入操作:

  • deleteOne()

  • deleteMany()

  • insertOne()

  • replaceOne()

  • updateOne()

  • updateMany()

要为后续写入操作选择不同的命名空间,请对 ClientBulkWrite实例调用 withCollection() 方法,如以下代码所示:

$movieCollection = $client->sample_mflix->movies;
$bulkWrite = $bulkWrite->withCollection($movieCollection);

以下部分介绍如何创建和使用 ClientBulkWrite 类来指定批量写入中的写入操作。执行批量操作部分演示了如何将 ClientBulkWrite对象传递给 bulkWrite() 方法以执行批量操作。

要指定插入操作,请在 ClientBulkWrite实例上调用 insertOne() 方法。

以下示例指定将文档插入到 sample_restaurants.restaurantssample_mflix.movies 集合中:

$restaurantCollection = $client->sample_restaurants->restaurants;
$movieCollection = $client->sample_mflix->movies;
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
$bulkWrite->insertOne(['name' => 'Mongo Deli', 'cuisine' => 'Sandwiches']);
$bulkWrite = $bulkWrite->withCollection($movieCollection);
$bulkWrite->insertOne(['title' => 'The Green Ray', 'year' => 1986]);

要指定对第一个匹配文档执行更新操作,请对 ClientBulkWrite实例调用 updateOne() 方法。

以下示例指定对 sample_restaurants.restaurants集合中 name 值为 'Dandelion Bakery' 的第一个文档进行 $set更新:

$restaurantCollection = $client->sample_restaurants->restaurants;
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
$bulkWrite->updateOne(
['name' => 'Dandelion Bakery'],
['$set' => ['grade' => 'B+']],
['upsert' => true],
);

要更新多个文档,请调用 updateMany() 方法。指定的操作会更新与查询过滤匹配的所有文档

以下示例指定对 sample_restaurants.restaurants集合中 name 值为 'Starbucks' 的所有匹配文档进行 $set更新:

$restaurantCollection = $client->sample_restaurants->restaurants;
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
$bulkWrite->updateMany(
['name' => 'Starbucks'],
['$set' => ['cuisine' => 'Coffee (Chain)']],
);

要指定对第一个匹配文档执行替换操作,请对 ClientBulkWrite实例调用 replaceOne() 方法。

以下示例指定对 sample_restaurants.restaurants集合中 name 值为 'Dandelion Bakery' 的第一个文档执行替换操作:

$restaurantCollection = $client->sample_restaurants->restaurants;
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
$bulkWrite->replaceOne(
['name' => 'Dandelion Bakery'],
['name' => 'Flower Patisserie', 'cuisine' => 'Bakery & Cafe'],
);

要指定对第一个匹配文档执行删除操作,请对 ClientBulkWrite实例调用 deleteOne() 方法。

以下示例指定删除 sample_restaurants.restaurants集合中第一个 borough 值为 'Queens' 的文档:

$restaurantCollection = $client->sample_restaurants->restaurants;
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
$bulkWrite->deleteOne(
['borough' => 'Queens'],
);

要删除多个文档,请调用 deleteMany() 方法。指定的操作将删除与查询过滤匹配的所有文档

以下示例指定删除 sample_restaurants.restaurants集合中 name 值包含两个连续 'p' 字符的所有文档:

$restaurantCollection = $client->sample_restaurants->restaurants;
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
$bulkWrite->deleteMany(
['name' => ['$regex' => 'p{2,}']],
);

构造 ClientBulkWrite实例来指定写入操作后,将其传递给 MongoDB\Client::bulkWrite() 方法。默认下,这些方法按照您在构造 ClientBulkWrite 时定义的顺序运行操作。

以下代码演示了如何使用 bulkWrite() 方法对多个命名空间执行批量写入操作:

$restaurantCollection = $client->sample_restaurants->restaurants;
$movieCollection = $client->sample_mflix->movies;
// Creates the bulk write command and sets the target namespace.
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
// Specifies insertion of one document.
$bulkWrite->insertOne(['name' => 'Mongo Deli', 'cuisine' => 'Sandwiches']);
// Specifies a `$set` update to one document with the upsert option
// enabled.
$bulkWrite->updateOne(
['name' => 'Dandelion Bakery'],
['$set' => ['grade' => 'B+']],
['upsert' => true],
);
// Changes the target namespace.
$bulkWrite = $bulkWrite->withCollection($movieCollection);
// Specifies insertion of one document.
$bulkWrite->insertOne(['title' => 'The Green Ray', 'year' => 1986]);
// Specifies deletion of documents in which `title` has two consective
// 'd' characters.
$bulkWrite->deleteMany(
['title' => ['$regex' => 'd{2,}']],
);
// Specifies replacement of one document.
$bulkWrite->replaceOne(
['runtime' => ['$gte' => 200]],
['title' => 'Seven Samurai', 'runtime' => 203],
);
// Performs the bulk write operation.
$result = $client->bulkWrite($bulkWrite);
// Prints a summary of results.
echo 'Inserted documents: ', $result->getInsertedCount(), PHP_EOL;
echo 'Modified documents: ', $result->getModifiedCount(), PHP_EOL;
echo 'Deleted documents: ', $result->getDeletedCount(), PHP_EOL;
Inserted documents: 2
Modified documents: 2
Deleted documents: 200

您可以通过将大量传递给将选项值指定为参数的 ClientBulkWrite 构造函数来修改客户端批量写入操作的行为。下表描述了可在大量中设立的选项:

选项
说明

bypassDocumentValidation

Specifies whether the operation bypasses document validation. This lets you modify documents that don't meet the schema validation requirements, if any exist. For more information about schema validation, see Schema Validation in the MongoDB Server manual.
The default is false.

comment

Attaches a comment to the operation. For more information, see the insert command fields guide in the MongoDB Server manual.

let

Specifies a document with a list of values to improve operation readability. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual.

ordered

If set to true: When a single write fails, the operation stops without performing the remaining writes and throws an exception.
If set to false: When a single write fails, the operation continues to attempt the remaining write operations, if any, then throws an exception.
The default is true.

verboseResults

Specifies whether to return verbose results.
The default is false.

以下示例创建一个 ClientBulkWrite实例并将 ordered 选项设置为 false

$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection(
$restaurantCollection,
['ordered' => false]
);

注意

无序行为

无序批量操作不保证执行顺序。为了优化运行时间,顺序可以与您列出的方式不同。假设您在无序批量写入中指定以下写入操作:

$bulkWrite->insertOne(['_id' => 4045, 'title' => 'The Green Ray']);
$bulkWrite->deleteOne(['_id' => 4045]);

由于库可能会先运行任一操作,因此结果可能显示一个已删除的文档,也可能显示未删除任何文档。

您还可以在调用 bulkWrite() 方法时传递选项,指定用于操作的客户端端会话或写关注(write concern)。

MongoDB\Client::bulkWrite() 方法返回一个 MongoDB\BulkWriteCommandResult对象。该类包含以下方法:

方法
说明

getInsertedCount()

Returns the total number of documents inserted by all insert operations in the bulk write command.

getMatchedCount()

Returns the total number of documents matched by all update and replace operations in the bulk write command.

getModifiedCount()

Returns the total number of documents modified by all update and replace operations in the bulk write command.

getUpsertedCount()

Returns the total number of documents upserted by all update and replace operations in the bulk write command.

getDeletedCount()

Return the total number of documents deleted by all delete operations in the bulk write command.

getInsertResults()

Returns a map of results of each successful insert operation. Each operation is represented by an integer key, which contains a document with information corresponding to the operation such as the inserted _id value.

getUpdateResults()

Returns a map of results of each successful update operation. Each operation is represented by an integer key, which contains a document with information corresponding to the operation.

getDeleteResults()

Returns a map of results of each successful delete operation. Each operation is represented by an integer key, which contains a document with information corresponding to the operation.

isAcknowledged()

Returns a boolean indicating whether the server acknowledged the bulk operation.

要运行批量写入操作,请将写入操作大量传递给 MongoDB\Collection::bulkWrite() 方法。使用以下语法指定写入操作:

[
[ 'deleteMany' => [ $filter ] ],
[ 'deleteOne' => [ $filter ] ],
[ 'insertOne' => [ $document ] ],
[ 'replaceOne' => [ $filter, $replacement, $options ] ],
[ 'updateMany' => [ $filter, $update, $options ] ],
[ 'updateOne' => [ $filter, $update, $options ] ],
]

提示

要学习;了解有关删除、插入、替换和更新操作的更多信息,请参阅“将数据写入MongoDB”部分中的指南。

调用 bulkWrite() 方法时,库会按照您在大量中指定的顺序自动运行写入操作。要学习;了解如何指示 bulkWrite() 以任意顺序运行写入操作,请参阅自定义批量写入操作部分。

此示例对restaurants集合运行以下写入操作:

  • 用于插入name值为'Mongo's Deli'的文档的插入操作

  • 用于更新name值为'Mongo's Deli'的文档的cuisine字段的更新操作

  • 删除操作,用于删除borough值为'Manhattan'的所有文档

$restaurantCollection = $client->sample_restaurants->restaurants;
$result = $restaurantCollection->bulkWrite(
[
[
'insertOne' => [
['name' => 'Mongo\'s Deli'],
['cuisine' => 'Sandwiches'],
['borough' => 'Manhattan'],
['restaurant_id' => '1234'],
],
],
[
'updateOne' => [
['name' => 'Mongo\'s Deli'],
['$set' => ['cuisine' => 'Sandwiches and Salads']],
],
],
[
'deleteMany' => [
['borough' => 'Manhattan'],
],
],
]
);

注意

当库运行批量操作时,它会使用目标集合的写关注(write concern)。无论执行顺序如何,驾驶员在尝试所有操作后都会报告所有写关注(write concern)错误。

您可以通过传递指定选项值的大量作为参数来修改MongoDB\Collection::bulkWrite()方法的行为。 下表描述了可在大量中设立的选项:

选项
说明

bypassDocumentValidation

Specifies whether the operation bypasses document validation. This lets you modify documents that don't meet the schema validation requirements, if any exist. For more information about schema validation, see Schema Validation in the MongoDB Server manual.
The default is false.

codec

Sets the codec to use for encoding or decoding documents. Bulk writes use the codec for insertOne() and replaceOne() operations. For more information, see the Codecs guide.

writeConcern

Sets the write concern for the operation. For more information, see Write Concern in the MongoDB Server manual.

let

Specifies a document with a list of values to improve operation readability. Values must be constant or closed expressions that don't reference document fields. For more information, see the let statement in the MongoDB Server manual.

ordered

If set to true: When a single write fails, the operation stops without performing the remaining writes and throws an exception.
If set to false: When a single write fails, the operation continues to attempt the remaining write operations, if any, then throws an exception.
The default is true.

comment

Attaches a comment to the operation. For more information, see the insert command fields guide in the MongoDB Server manual.

session

Specifies the client session to associate with the operation.

以下示例调用bulkWrite()方法执行插入和删除操作,并将ordered选项设置为false

$result = $restaurantCollection->bulkWrite(
[
[
'insertOne' => [
['name' => 'Mongo\'s Pizza'],
['cuisine' => 'Italian'],
['borough' => 'Queens'],
['restaurant_id' => '5678'],
],
],
[
'deleteOne' => [
['restaurant_id' => '5678'],
],
],
],
['ordered' => false]
);

如果库先运行插入操作,则会删除一个文档。 如果它先运行删除操作,则不会删除任何文档。

注意

无序行为

无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。

MongoDB\Collection::bulkWrite() 方法返回一个 MongoDB\BulkWriteResult对象。该类包含以下方法:

方法
说明

getInsertedCount()

Returns the total number of documents inserted by all insert operations in the bulk write command.

getInsertedIds()

Returns a map of _id field values for documents inserted by all insert operations in the bulk write command.

getMatchedCount()

Returns the total number of documents matched by all update and replace operations in the bulk write command.

getModifiedCount()

Returns the total number of documents modified by all update and replace operations in the bulk write command.

getUpsertedCount()

Returns the total number of documents upserted by all update and replace operations in the bulk write command.

getUpsertedIds()

Returns a map of _id field values for documents upserted by all update and replace operations in the bulk write command.

getDeletedCount()

Return the total number of documents deleted by all delete operations in the bulk write command.

isAcknowledged()

Returns a boolean indicating whether the server acknowledged the bulk operation.

要了解如何执行单个写入操作,请参阅以下指南:

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档:

后退

替换

在此页面上