Docs Menu

一括書き込み操作

このガイドでは、 Javaドライバーで一括操作を使用する方法を学習できます。

単一の 作成、置換、アップデート、または削除操作を実行するには、対応するメソッドを使用できます。 例、1 つのドキュメントを挿入し、1 つのドキュメントを置き換えるには、insertOne() メソッドと replaceOne() メソッドを使用できます。 これらのメソッドを使用すると、クライアントは操作ごとにデータベースを 1 回呼び出します。

一括書き込み操作 を使用すると、より少ないデータベース呼び出しで複数の書き込み操作を実行できます。 次のレベルで一括書き込み操作を実行できます。

  • コレクション :MongoCollection.bulkWrite() メソッドを使用して、単一のコレクションに対して一括書き込み操作を実行できます。このメソッドでは、それぞれの書き込み操作に少なくとも 1 回のデータベース呼び出しが必要です。 例、MongoCollection.bulkWrite() は 1 回の呼び出しで複数のアップデート操作を実行しますが、挿入操作と置換操作の場合はデータベースに 2 回個別の呼び出しを行います。

  • クライアント :アプリケーションがMongoDB Serverバージョン8.0 以降に接続している場合は、MongoClient.bulkWrite() メソッドを使用して、同じクラスター内の複数のコレクションとデータベースに対して一括書込み操作を実行できます。このメソッドは、1 回のデータベース呼び出しですべての書き込み操作を実行します。

一括書き込み操作には、1 つ以上の書き込み操作が含まれます。 コレクションレベルで一括書き込み操作を実行するには、WriteModel ドキュメントの ListMongoCollection.bulkWrite() メソッドに渡します。 WriteModel は 書込み操作を表すモデルです。

MongoCollection.bulkWrite() メソッドは、個別のデータベース呼び出しでそれぞれの種類の書込み操作を実行します。 例、DeleteOneModelDeleteManyModelReplaceOneModel オブジェクトを メソッドに渡すと、削除操作の呼び出しと置換操作の 2 回の呼び出しが実行されます。

注意

クライアントが操作を個別のデータベース呼び出しに分割するときに、一括書き込み操作が順序付けられていない場合は、効率のために操作の順序を並べ替えることがあります。 操作の実行順序の詳細については、「 実行順序 」セクションを参照してください。

次のセクションでは、各WriteModelドキュメントの作成方法と使用方法を示します。 各セクションの例では、 peopleコレクション内の次のドキュメントを使用します。

{ "_id": 1, "name": "Karen Sandoval", "age": 31 }
{ "_id": 2, "name": "William Chin", "age": 54 }
{ "_id": 8, "name": "Shayla Ray", "age": 20 }

このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。

挿入操作を実行するには、挿入するドキュメントを指定するInsertOneModelを作成します。 複数のドキュメントを挿入するには、挿入するドキュメントごとにInsertOneModelを作成する必要があります。

次の例では、人物を説明する 2 つのドキュメントに対してInsertOneModelを作成しています。

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をスローします。

次の例では、 _id13である 2 つのドキュメントを挿入しようとしています。

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={}}].

3_idを持つドキュメントが挿入されなかった理由については、「実行順序 」セクションを参照してください。

このセクションで説明されるメソッドとクラスの詳細については、 InsertOneModel APIドキュメント を参照してください。

置換操作を実行するには、置換ドキュメントで置き換えるドキュメントのクエリフィルターを指定するReplaceOneModelを作成します。

重要

bulkWrite()を実行する場合、 ReplaceOneModelはコレクションの一意のインデックス制約に違反するドキュメントを変更できません。クエリフィルターに一致しない場合は、モデルはドキュメントを置換しません。

次の例では、 ReplaceOneModelを作成して、 _id1であるドキュメントを、 locationフィールドが追加されたドキュメントに置き換えます。

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

複数のドキュメントが ReplaceOneModelインスタンスで指定されたクエリフィルターに一致する場合、その操作は最初の結果を置き換えます。次のコードに示すように、サーバーが置換操作を実行する前に、一致したドキュメントに順序を適用するために、ReplaceOptionsインスタンスで並べ替えを指定できます。

ReplaceOptions options = ReplaceOptions.sort(Sorts.ascending("_id"));

このセクションで述べられたメソッドとクラスの詳細については、次のリソースを参照してください。

アップデート操作を実行するには、アップデート内容を使用してアップデートするドキュメントのクエリフィルターを指定するUpdateOneModelまたはUpdateManyModelを作成します。

UpdateOneModelはクエリフィルターに一致する最初のドキュメントを更新し、 UpdateManyModelはクエリフィルターに一致するすべてのドキュメントを更新します。

重要

bulkWrite()を実行する場合、 UpdateOneModelUpdateManyModelはコレクションの一意のインデックス制約に違反するドキュメントを変更できません。クエリフィルターに一致しない場合、モデルはドキュメントを更新しません。

次の例では、 _id2であるドキュメントのageフィールドを更新するためのUpdateOneModelを作成します。

UpdateOneModel<Document> updateDoc = new UpdateOneModel<>(
Filters.eq("_id", 2),
Updates.set("age", 31));

複数のドキュメントが UpdateOneModelインスタンスで指定されたクエリフィルターに一致する場合、この操作最初の結果が更新されます。次のコードに示すように、サーバーが更新操作を実行する前に、一致したドキュメントに順序を適用するために、UpdateOptionsインスタンスで並べ替えを指定できます。

UpdateOptions options = UpdateOptions.sort(Sorts.ascending("_id"));

このセクションで述べられたメソッドとクラスの詳細については、次のリソースを参照してください。

削除操作を実行するには、削除するドキュメントのクエリフィルターを指定するDeleteOneModelまたはDeleteManyModelを作成します。

DeleteOneModelはクエリフィルターに一致する最初のドキュメントを削除し、 DeleteManyModelはクエリフィルターに一致するすべてのドキュメントを削除します。

重要

bulkWrite()を実行するとき、クエリフィルターに一致しない場合、 DeleteOneModelDeleteManyModelはドキュメントを削除しません。

次の例では、 _id1であるドキュメントを削除するためにDeleteOneModelを作成しています。

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

このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。

bulkWrite()メソッドでは、一括操作の実行が順序付きか順序なしかを指定する 2 番目のパラメータとして任意のBulkWriteOptionsを受け入れます。

デフォルトでは、 bulkWrite()メソッドは一括操作を順番に実行します。 つまり、エラーが発生するまで、一括操作はリストに追加した順序で実行されます(存在する場合)。

次の例では、これらの一括操作を実行します。

  • : "Zaynab Omar"name値と37age値を持つドキュメントを挿入する操作

  • _id1であるドキュメントを、 locationフィールドを含む新しいドキュメントに置き換える操作

  • ドキュメントを"Zaynab Omar"name値で更新し、 name"Zaynab Hassan"に変更する操作

  • ageの値が50より大きいすべてのドキュメントを削除する操作

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(insertDoc);
bulkOperations.add(replaceDoc);
bulkOperations.add(updateDoc);
bulkOperations.add(deleteDoc);
// Runs a bulk write operation for the specified the insert, replace, update, and delete WriteModels in order
collection.bulkWrite(bulkOperations);

この例の実行後、コレクションには次のドキュメントが含まれます。

{ "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" }
{ "_id": 8, "name": "Shayla Ray", "age": 20 }
{ "_id": 6, "name": "Zaynab Hassan", "age": 37 }

また、 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": 1, "name": "Sandy Kane", "location": "Helena, MT" }
{ "_id": 8, "name": "Shayla Ray", "age": 20 }
{ "_id": 6, "name": "Zaynab Omar", "age": 37 }

このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。

注意

セットアップ例

この例では、接続 URI を使用してMongoDBのインスタンスに接続します。 MongoDBインスタンスへの接続の詳細については、「 MongoClient の作成 」ガイドを参照してください。この例では、 Atlasサンプルデータセット に含まれる sample_mflixデータベースの moviesコレクションも使用します。 「 Atlas を使い始める 」ガイドに従って、 MongoDB Atlasの無料階層のデータベースにロードできます。

The following code is a complete, standalone file that performs the following actions:

  1. Creates a list of instances of the InsertOneModel, UpdateOneModel, DeleteOneModel, and ReplaceOneModel classes.

  2. Runs an ordered bulkWrite() operation that performs the writes specified in the model list.

// Runs bulk write operations on a collection by using the Java driver
package org.example;
import java.util.Arrays;
import org.bson.Document;
import com.mongodb.MongoException;
import com.mongodb.bulk.BulkWriteResult;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.DeleteOneModel;
import com.mongodb.client.model.InsertOneModel;
import com.mongodb.client.model.ReplaceOneModel;
import com.mongodb.client.model.UpdateOneModel;
import com.mongodb.client.model.UpdateOptions;
public class BulkWrite {
public static void main(String[] args) {
// Replace the uri string with your MongoDB deployment's connection string
String uri = "<connection string uri>";
try (MongoClient mongoClient = MongoClients.create(uri)) {
MongoDatabase database = mongoClient.getDatabase("sample_mflix");
MongoCollection<Document> collection = database.getCollection("movies");
// Runs a bulk write operation for the specified insert, update, delete, and replace operations
BulkWriteResult result = collection.bulkWrite(
Arrays.asList(
new InsertOneModel<>(new Document("name", "A Sample Movie")),
new InsertOneModel<>(new Document("name", "Another Sample Movie")),
new InsertOneModel<>(new Document("name", "Yet Another Sample Movie")),
new UpdateOneModel<>(new Document("name", "A Sample Movie"),
new Document("$set", new Document("name", "An Old Sample Movie")),
new UpdateOptions().upsert(true)),
new DeleteOneModel<>(new Document("name", "Yet Another Sample Movie")),
new ReplaceOneModel<>(new Document("name", "Yet Another Sample Movie"),
new Document("name", "The Other Sample Movie").append("runtime", "42"))
));
// Prints the number of inserted, updated, and deleted documents
System.out.println("Result statistics:" +
"\ninserted: " + result.getInsertedCount() +
"\nupdated: " + result.getModifiedCount() +
"\ndeleted: " + result.getDeletedCount());
}
}
}
Result statistics:
inserted: 3
updated: 2
deleted: 1

MongoDB Server 8.0 以降を実行中配置に接続する場合、MongoClient.bulkWrite() メソッドを使用して同じクラスター内の複数のデータベースとコレクションに書込み (write) できます。 MongoClient.bulkWrite() メソッドは、1 回の呼び出しですべての書き込み操作を実行します。

MongoClient.bulkWrite() メソッドは、さまざまな書込み操作を表すために ClientNamespacedWriteModel インスタンスのリストを受け取ります。 インスタンスメソッドを使用して、ClientNamespacedWriteModel インターフェースのインスタンスを構築できます。 例、ClientNamespacedInsertOneModel のインスタンスは1 つのドキュメントを挿入する操作を表します。このモデルは ClientNamespacedWriteModel.insertOne() メソッドを使用して作成できます。

注意

一括書き込みエラー

書き込み操作のいずれかが失敗した場合、ドライバーは ClientBulkWriteException を発生させ、それ以上の個々の操作を実行しません。 ClientBulkWriteException には ClientBulkWriteException.getWriteErrors() メソッドを使用してアクセスできる BulkWriteError が含まれており、個々の障害の詳細が提供されます。

モデルとそれに対応するインスタンスメソッドは、以下の表に説明されています。

モデル
インスタンス メソッド
説明
パラメーター

ClientNamespacedInsertOneModel

insertOne()

namespace にドキュメントを挿入するためのモデルを作成します。

namespace: 書き込み先のデータベースとコレクション

document: 挿入するドキュメント

ClientNamespacedUpdateOneModel

updateOne()

filter に一致する namespace 内の最初のドキュメントを更新するためのモデルを作成します。

namespace: 書き込み先のデータベースとコレクション

filter: 更新するドキュメントを選択するフィルター

update: 一致するドキュメントに適用するアップデート

updatePipeline: 一致するドキュメントに適用するパイプラインを更新

options:(任意)ドキュメント更新時に適用するオプション

update または updatePipeline パラメーターのいずれかに値を渡す必要があります。

ClientNamespacedUpdateManyModel

updateMany()

filter に一致する namespace 内のすべてのドキュメントを更新するモデルを作成します。

namespace: 書き込み先のデータベースとコレクション

filter: 更新するドキュメントを選択するフィルター

update: 一致するドキュメントに適用する更新

updatePipeline: 一致するドキュメントに適用するパイプラインを更新

options:(任意)ドキュメント更新時に適用するオプション

update または updatePipeline パラメーターのいずれかに値を渡す必要があります。

ClientNamespacedReplaceOneModel

replaceOne()

filter に一致する namespace 内の最初のドキュメントを置き換えるモデルを作成します。

namespace: 書き込み先のデータベースとコレクション

filter: 置き換えるドキュメントを選択するフィルター

replacement: 置換ドキュメント

options:(任意)ドキュメントの置き換え時に適用するオプション

ClientNamespacedDeleteOneModel

deleteOne()

filter に一致する namespace 内の最初のドキュメントを削除するためのモデルを作成します。

namespace: 書き込み先のデータベースとコレクション

filter: 削除するドキュメントを選択するフィルター

option:(任意)ドキュメントの削除時に適用するオプション

ClientNamespacedDeleteManyModel

deleteMany()

filter に一致する namespace 内のすべてのドキュメントを削除するモデルを作成します。

namespace: 書き込み先のデータベースとコレクション

filter: 削除するドキュメントを選択するフィルター

option:(任意)ドキュメントの削除時に適用するオプション

次のセクションでは、クライアントのbulkWrite() メソッドを使用する方法の例を示します。

このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。

この例では、 bulkWrite() メソッドを使用して 2 つのドキュメントを挿入する方法を示しています。 一方のドキュメントは db.peopleコレクションに挿入され、もう一方のドキュメントは db.thingsコレクションに挿入されます。 MongoNamespaceインスタンスは、各書き込み操作が適用されるデータベースとコレクションを定義します。

MongoNamespace peopleNamespace = new MongoNamespace("db", "people");
MongoNamespace thingsNamespace = new MongoNamespace("db", "things");
List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>();
bulkOperations.add(ClientNamespacedWriteModel
.insertOne(
peopleNamespace,
new Document("name", "Julia Smith")
)
);
bulkOperations.add(ClientNamespacedWriteModel
.insertOne(
thingsNamespace,
new Document("object", "washing machine")
)
);
ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations);

次の例は、bulkWrite() メソッドを使用して、db.people コレクションと db.things コレクション内の既存のドキュメントを更新する方法を示しています。

MongoNamespace peopleNamespace = new MongoNamespace("db", "people");
MongoNamespace thingsNamespace = new MongoNamespace("db", "things");
List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>();
bulkOperations.add(ClientNamespacedWriteModel.updateOne(
peopleNamespace,
Filters.eq("name", "Freya Polk"),
Updates.inc("age", 1)
)
);
bulkOperations.add(ClientNamespacedWriteModel.updateMany(
thingsNamespace,
Filters.eq("category", "electronic"),
Updates.set("manufacturer", "Premium Technologies")
)
);
ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations);

この例では、peopleコレクションで name 値が "Freya Polk" であるドキュメントで、ageフィールドの値を 1 ずつ増加させます。また、thingsコレクション内で category 値が "electronic" であるすべてのドキュメントの manufacturerフィールドの値を "Premium Technologies" に設定します。

If multiple documents match the query filter specified in a ClientNamespacedUpdateOneModel instance, the operation updates the first result. You can specify a sort order in a ClientUpdateOneOptions instance to apply an order to matched documents before the driver performs the update operation, as shown in the following code:

ClientUpdateOneOptions options = ClientUpdateOneOptions
.clientUpdateOneOptions()
.sort(Sorts.ascending("_id"));

The following example shows how to use the bulkWrite() method to replace existing documents in the db.people and db.things collections:

MongoNamespace peopleNamespace = new MongoNamespace("db", "people");
MongoNamespace thingsNamespace = new MongoNamespace("db", "things");
List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>();
bulkOperations.add(ClientNamespacedWriteModel.replaceOne(
peopleNamespace,
Filters.eq("_id", 1),
new Document("name", "Frederic Hilbert")
)
);
bulkOperations.add(ClientNamespacedWriteModel.replaceOne(
thingsNamespace,
Filters.eq("_id", 1),
new Document("object", "potato")
)
);
ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations);

この例が正常に実行されると、peopleコレクション内の _id 値が 1 であるドキュメントは、新しいドキュメントに置き換えられます。 _id 値が 1 である thingsコレクション内のドキュメントは、 新しいドキュメントに置き換えられます。

複数のドキュメントが ClientNamespacedReplaceOneModelインスタンスで指定されたクエリフィルターに一致する場合、その操作は最初の結果を置き換えます。次のコードに示すように、ClientReplaceOneOptionsインスタンスでソート順序を指定して、ドライバーが置換操作を実行する前に一致したドキュメントに順序を適用できます。

ClientReplaceOneOptions options = ClientReplaceOneOptions
.clientReplaceOneOptions()
.sort(Sorts.ascending("_id"));

一括書き込み操作を実行中ときにオプションを指定するには、ClientBulkWriteOptions のインスタンスを bulkWrite() メソッドに渡します。

デフォルトでは 、一括操作内の個々の操作は、エラーが発生するまで、または正常に実行されるまで、指定された順序で実行されます。 ただし、ClientBulkWriteOptions インターフェースの ordered() メソッドに false を渡すと、順序なしで書込み操作を実行できます。 順序なし オプションを使用する場合、エラーが発生する操作はbulkWrite() メソッドの呼び出しで他の書込み操作の実行を妨げるものではありません。

次のコードでは、ClientBulkWriteOptions のインスタンスに ordered() メソッドを設定し、一括書込み操作を実行して複数のドキュメントを挿入します。

MongoNamespace namespace = new MongoNamespace("db", "people");
ClientBulkWriteOptions options = ClientBulkWriteOptions
.clientBulkWriteOptions()
.ordered(false);
List<ClientNamespacedWriteModel> bulkOperations = new ArrayList<>();
bulkOperations.add(
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("_id", 1).append("name", "Rudra Suraj")
)
);
// Causes a duplicate key error
bulkOperations.add(
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("_id", 1).append("name", "Mario Bianchi")
)
);
bulkOperations.add(
ClientNamespacedWriteModel.insertOne(
namespace,
new Document("name", "Wendy Zhang")
)
);
ClientBulkWriteResult result = mongoClient.bulkWrite(bulkOperations, options);

重複キーを持つドキュメントを挿入する書込み操作ではエラーが発生しますが、書込み操作は順序付けがないため、他の操作が実行されます。

To learn more about the methods and classes used to perform bulk write operations in this section, see the following API documentation: