Docs 菜单
Docs 主页
/ / /
java sync
/ / /

批量操作

在此页面上

  • Overview
  • 执行批量操作
  • 插入操作
  • 替换操作
  • 更新操作
  • 删除操作
  • 执行顺序
  • 命令执行
  • 无序执行
  • 总结

在本指南中,您可以了解如何在 MongoDB Java 驱动程序中使用批量操作。

要执行创建、替换、更新或删除操作,请使用相应的方法。例如,要在集合中插入一个文档、更新多个文档和删除一个文档,可使用 insertOne()updateMany()deleteOne() 方法。

在执行这些操作时,MongoClient 会对数据库调用每个操作。您可使用批量操作,将对数据库的调用次数减少到一次。

批量操作包括大量写操作。要执行批量操作,请向 bulkWrite() 方法传递 List 文档的 WriteModelWriteModel 是表示任何写操作的模型。

以下部分介绍如何创建和使用每个WriteModel文档。 每个部分中的示例包含一个collection中的以下文档:

{ "_id": 1 }
{ "_id": 2 }

有关本节中提到的方法和类的详情,请参阅以下 API 文档:

  • bulkWrite()

  • WriteModel

  • BulkWriteOptions

如需执行插入操作,请创建 InsertOneModel,指定要插入的文档。如需插入多个文档,必须为每个要插入的文档创建一个 InsertOneModel

以下示例为两个文档创建一个InsertOneModel ,其中_id值为“3”和“4”:

InsertOneModel<Document> juneDoc = new InsertOneModel<>(new Document("name", "June Carrie")
.append("age", 17));
InsertOneModel<Document> kevinDoc = new InsertOneModel<>(new Document("name", "Kevin Moss")
.append("age", 22));

重要

执行 bulkWrite() 时,InsertOneModel 不能插入集合已存在的具有 _id 的文档。相反,该方法会抛出 MongoBulkWriteException

以下示例尝试插入两个文档,其中_id为“1”和“3”:

try {
List<WriteModel<Document>> bulkOperations = new ArrayList<>();
// Creates instructions to insert documents
InsertOneModel<Document> doc1 = new InsertOneModel<>(new Document("_id", 1));
InsertOneModel<Document> doc3 = new InsertOneModel<>(new Document("_id", 3));
bulkOperations.add(doc1);
bulkOperations.add(doc3);
// Runs a bulk write operation for the specified insert WriteModels
collection.bulkWrite(bulkOperations);
// Prints a message if any exceptions occur during the bulk write operation
} catch (MongoBulkWriteException e){
System.out.println("A MongoBulkWriteException occurred with the following message: " + e.getMessage());
}

以下显示了上述代码的输出:

A MongoBulkWriteException occurred with the following message:
Bulk write operation error on server sample-shard-00-02.pw0q4.mongodb.net:27017.
Write errors: [BulkWriteError{index=0, code=11000, message='E11000 duplicate key
error collection: crudOps.bulkWrite index: _id_ dup key: { _id: 1 }', details={}}].

要了解为什么未插入_id为 " 3 " 的文档,请参阅“执行顺序”部分。

有关本节提及的方法和类的详情,请参阅 InsertOneModel API 文档。

要执行替换操作,请创建 ReplaceOneModel,为要替换为替换文档的文档指定查询筛选器。

重要

执行 bulkWrite() 时,ReplaceOneModel 无法对违反集合唯一索引约束的文档进行更改,并且如果查询筛选器没有匹配项,则模型不会替换文档。

以下示例创建了一个ReplaceOneModel ,以将_id为“1”的文档替换为包含附加字段的文档:

ReplaceOneModel<Document> doc3 = new ReplaceOneModel<>(
Filters.eq("_id", 1),
new Document("name", "Celine Stork")
.append("location", "San Diego, CA"));

有关部分提及的方法和类的更多信息,请参阅以下资源:

要执行更新操作,请创建 UpdateOneModelUpdateManyModel 从而为要更新的文档指定查询筛选器。

UpdateOneModel 更新与查询筛选器匹配的第一个文档,UpdateManyModel 更新与查询筛选器匹配的所有文档。

重要

执行 bulkWrite() 时,UpdateOneModelUpdateManyModel 无法对违反集合唯一索引约束的文档进行更改,并且如果查询筛选器没有匹配项,则模型不会更新任何文档。

以下示例创建一个UpdateOneModel ,用于将_id为“2”的文档更新为包含附加字段的文档:

UpdateOneModel<Document> doc3 = new UpdateOneModel<>(
Filters.eq("_id", 2),
Updates.set("x", 8));

有关部分提及的方法和类的更多信息,请参阅以下资源:

要执行删除操作,请创建 DeleteOneModelDeleteManyModel,指定要删除文档的查询筛选器。

DeleteOneModel 删除与查询筛选器匹配的第一个文档,DeleteManyModel 删除与查询筛选器匹配的所有文档。

重要

执行 bulkWrite() 时,如果没有与查询筛选器匹配的文件,则 DeleteOneModelDeleteManyModel 不会删除任何文件。

以下示例创建一个DeleteOneModel来删除_id为“1”的文档:

DeleteOneModel<Document> doc3 = new DeleteOneModel<>(Filters.eq("_id", 1));

有关本节中提到的方法和类的详情,请参阅以下 API 文档:

bulkWrite()方法接受可选的BulkWriteOptions作为第二个参数,以指定是要按有序还是无序执行批量操作。

默认情况下,bulkWrite() 方法按顺序执行批量操作。这意味着批量操作将按照您添加到列表中的顺序执行,直到出现错误(如有)。

以下示例执行这些批量操作:

  • 针对_id为“3”的文档的插入操作

  • _id为 "1" 的文档替换为包含附加字段的文档的替换操作

  • 针对_id为“3”的文档到包含附加字段的文档的更新操作

  • 对包含值为“2”的字段x的所有文档的删除操作

List<WriteModel<Document>> bulkOperations = new ArrayList<>();
// Creates instructions to insert a document
InsertOneModel<Document> insertDoc = new InsertOneModel<>(new Document("_id", 6)
.append("name", "Zaynab Omar")
.append("age", 37));
// Creates instructions to replace the first document matched by the query
ReplaceOneModel<Document> replaceDoc = new ReplaceOneModel<>(Filters.eq("_id", 1),
new Document("name", "Sandy Kane")
.append("location", "Helena, MT"));
// Creates instructions to update the first document matched by the query
UpdateOneModel<Document> updateDoc = new UpdateOneModel<>(Filters.eq("name", "Zaynab Omar"),
Updates.set("name", "Zaynab Hassan"));
// Creates instructions to delete all documents matched by the query
DeleteManyModel<Document> deleteDoc = new DeleteManyModel<>(Filters.gt("age", 50));
bulkOperations.add(doc1);
bulkOperations.add(doc2);
bulkOperations.add(doc3);
bulkOperations.add(doc4);
// Runs a bulk write operation for the specified the insert, replace, update, and delete WriteModels in order
collection.bulkWrite(bulkOperations);

运行此示例后,集合将包含以下文档:

{ "_id": 2 }

您还可以在 BulkWriteOptionsorder() 方法中指定“false”,从而以任意顺序执行批量操作。这意味着无论是否出现错误,所有写操作都会执行,而在出现任何错误的情况下,将在最后报告批量操作。

在前面示例的基础上,添加以下内容,指定以任意顺序执行批量操作:

BulkWriteOptions options = new BulkWriteOptions().ordered(false);
// Runs a bulk write operation for the specified insert, replace, update, and delete WriteModels in any order
collection.bulkWrite(bulkOperations, options);

注意

无序批量操作不保证执行顺序。为了优化运行时间,顺序可能与您所列顺序不同。

在前一示例中,如果 bulkWrite() 方法决定在更新操作之后执行插入操作,则更新操作不会导致任何变化,因为该文档当时并不存在。随后,您的集合会包含以下文档:

{ "_id": 2 }
{ "_id": 3 }

有关本节中提到的方法和类的详情,请参阅以下 API 文档:

要执行批量操作,您需要创建 WriteModel 文档列表并将其传递给 bulkWrite() 方法。

共有 6 个不同的 WriteModel 文档:InsertOneModelReplaceOneModelUpdateOneModelUpdateManyModelDeleteOneModelDeleteManyModel

有两种方法可以执行 bulkWrite() 方法:

  • 有序,按顺序执行批量操作,直到出现错误(如有)

  • 无序,以任何顺序执行所有批量操作,并在最后报告错误(如果有)

后退

在单个操作中插入或更新