Docs Menu

一括操作

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

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

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

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

  • クライアント :アプリケーションがMongoDBサーバーバージョン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 }

このデータは、次のKotlinデータクラスによってモデル化されます。

data class Person(
@BsonId val id: Int,
val name: String,
val age: Int? = null,
val location: String? = null
)

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

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

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

val juneDoc = InsertOneModel(Person(3, "June Carrie", 17))
val kevinDoc = InsertOneModel(Person(4, "Kevin Moss", 22))

重要

bulkWrite()操作を実行する場合、 InsertOneModelはコレクション内にすでに存在する_idを含むドキュメントを挿入できません。 この場合ドライバーはMongoBulkWriteExceptionをスローします。

次の例では、 _idの値が13である 2 つのドキュメントを挿入しようとしています。 コレクションには_id1であるドキュメントがすでにあるため、操作はエラーになります。

try {
val bulkOperations = listOf(
(InsertOneModel(Person(1, "James Smith", 13))),
(InsertOneModel(Person(3, "Colin Samuels")))
)
val bulkWrite = collection.bulkWrite(bulkOperations)
} catch (e: MongoBulkWriteException) {
println("A MongoBulkWriteException occurred with the following message: " + e.message)
}
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フィールドを含むドキュメントに置き換えます。

val filter = Filters.eq("_id", 1)
val insert = Person(1, "Celine Stork", location = "San Diego, CA")
val doc = ReplaceOneModel(filter, insert)

If multiple documents match the query filter specified in the ReplaceOneModel instance, the operation replaces the first result. You can specify a sort in a ReplaceOptions instance to apply an order to matched documents before the server performs the replace operation, as shown in the following code:

val opts = ReplaceOptions().sort(Sorts.ascending("_id"))

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

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

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

重要

bulkWrite()を実行する場合、 UpdateOneModel型とUpdateManyModel型はコレクションの一意のインデックス制約に違反する変更を行うことはできません。 さらに、クエリフィルターに一致するものがない場合、モデルは更新操作を実行しません。

次の例では、 _id2であるドキュメントでageフィールドを1ずつ増加させるためのUpdateOneModelを作成します。

val filter = Filters.eq("_id", 2)
val update = Updates.inc(Person::age.name, 1)
val doc = UpdateOneModel<Person>(filter, update)

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

val opts = UpdateOptions().sort(Sorts.ascending("_id"))

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

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

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

重要

bulkWrite()の実行時に、クエリフィルターに一致しない場合、 DeleteOneModelおよびDeleteManyModelタイプはドキュメントを削除しません。

次の例では、 _id1であるドキュメントを削除するためのDeleteOneModelと、 ageの値が30より小さいドキュメントを削除するためのDeleteManyModelを作成します。

val deleteId1 = DeleteOneModel<Person>(Filters.eq("_id", 1))
val deleteAgeLt30 = DeleteManyModel<Person>(Filters.lt(Person::age.name, 30))

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

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

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

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

  • name"Zaynab Omar"で、 age37であるドキュメントの挿入操作

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

  • _id6であるドキュメントの更新操作でnameフィールドを変更

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

val insertMdl = InsertOneModel(Person(6, "Zaynab Omar", 37))
val replaceMdl = ReplaceOneModel(
Filters.eq("_id", 1),
Person(1, "Sandy Kane", location = "Helena, MT")
)
val updateMdl = UpdateOneModel<Person>(
Filters.eq("_id", 6),
Updates.set(Person::name.name, "Zaynab Hassan")
)
val deleteMdl = DeleteManyModel<Person>(Filters.gt(Person::age.name, 50))
val bulkOperations = listOf(
insertMdl,
replaceMdl,
updateMdl,
deleteMdl
)
val result = 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 }

また、 BulkWriteOptionsオブジェクトのordered()メソッドにfalseを渡すことで、任意の順序で一括操作を実行することもできます。 This means that all the write operations execute regardless of errors. エラーが発生した場合、ドライバーは最後にそれを報告します。

次のコードは、実行順序なしの一括操作を実行する方法を示しています。

val options = BulkWriteOptions().ordered(false)
val unorderedResult = 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 ドキュメントを参照してください。

MongoDBサーバー8.0 以降を実行中配置に接続する場合、MongoClient.bulkWrite() メソッドを使用して、同じクラスター内の複数のデータベースとコレクションに書込むことができます。 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() メソッドを使用する方法の例を示します。 サンプルデータは、次のKotlinデータ クラスによってモデル化されます。

data class Person(
@BsonId val id: Int,
val name: String,
val age: Int? = null,
)
data class Object(
@BsonId val id: Int,
val type: String,
val category: String? = null,
val manufacturer: String? = null,
)

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

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

val docsToInsert = mutableListOf<ClientNamespacedWriteModel>()
docsToInsert.add(
ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "people"),
Person(2, "Julia Smith")
)
)
docsToInsert.add(
ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "objects"),
Object(2, "washing machine")
)
)
val clientBulkResult = client.bulkWrite(docsToInsert)

The following example shows how to use the bulkWrite() method to update existing documents in the sample_db.people and sample_db.objects collections:

val docsToInsert = mutableListOf<ClientNamespacedWriteModel>()
docsToInsert.add(
ClientNamespacedWriteModel
.updateOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::name.name, "Freya Polk"),
Updates.inc(Person::age.name, 1)
)
)
docsToInsert.add(
ClientNamespacedWriteModel
.updateMany(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::category.name, "electronic"),
Updates.set(Object::manufacturer.name, "Premium Technologies")
)
)
val clientBulkResult = client.bulkWrite(docsToInsert)

This example increments the value of the age field by 1 in the document that has a name value of "Freya Polk" in the people collection. It also sets the value of the manufacturer field to "Premium Technologies" in all documents that have a category value of "electronic" in the objects collection.

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 server performs the update operation, as shown in the following code:

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

次の例では、 bulkWrite() メソッドを使用して、sample_db.people コレクションと sample_db.objects コレクション内の既存のドキュメントを置き換える方法を示します。

val docsReplacements = mutableListOf<ClientNamespacedWriteModel>()
docsReplacements.add(
ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::id.name, 1),
Person(1, "Frederic Hilbert")
)
)
docsReplacements.add(
ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::id.name, 1),
Object(1, "ironing board")
)
)
val clientBulkResult = client.bulkWrite(docsReplacements)

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

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

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

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

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

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

val namespace = MongoNamespace("sample_db", "people")
val options = ClientBulkWriteOptions
.clientBulkWriteOptions()
.ordered(false)
val bulkOperations = listOf(
ClientNamespacedWriteModel.insertOne(
namespace,
Person(2, "Rudra Suraj")
),
// Causes duplicate key error
ClientNamespacedWriteModel.insertOne(
namespace,
Person(2, "Wendy Zhang")
),
ClientNamespacedWriteModel.insertOne(
namespace,
Person(4, "Mario Bianchi")
)
)
val result = client.bulkWrite(bulkOperations, options)

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

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

一括操作を実行するには、作成して WriteModel インスタンスのリストを bulkWrite() メソッドに渡します。

6 には異なる WriteModel サブタイプがあります: InsertOneModelReplaceOneModelUpdateOneModelUpdateManyModelDeleteOneModelDeleteManyModel

bulkWrite()メソッドを実行するには次の 2 つの方法があります。

  • 順序付き: エラーが発生するまで一括操作を順番に実行します

  • 順序付けなし: すべての一括操作を任意の順序で実行し、終了時にエラーを報告します

コレクションbulkWrite コマンドの詳細については、 db を参照してください。コレクション.bulkWrite()MongoDB参照をサーバーしてください。

MongoDBサーバーバージョン 8.0 以降を実行中配置に接続する場合、MongoClient.bulkWrite() メソッドを使用して、複数のデータベースとコレクションに対して一括操作を一度に実行できます。

クライアント一括操作 を実行するには、ClientNamespacedWriteModel インスタンスのリストを作成してこのメソッドに渡します。

書込み操作を表すために使用される ClientNamespacedWriteModel には 6 つのサブタイプがあります。 これらの書込みモデルを構築するには、対応する ClientNamespacedWriteModel メソッド insertOne()updateOne()updateMany()replaceOne()deleteOne()deleteMany() を使用できます。 これらのメソッドは、書き込み先のデータベースとコレクションを定義する MongoNamespaceオブジェクトを受け取ります。

MongoClient.bulkWrite() メソッドは ClientBulkWriteOptionsオブジェクトを受け取り、コマンドの実行方法に関するさまざまなオプションを指定することもできます。

クライアントbulkWrite コマンドの詳細については、 MongoDBサーバーマニュアルの bulkWrite() メソッドに関する参照を参照してください。