一括操作
Overview
このガイドでは、MongoDB Kotlin ドライバーで一括操作を使用する方法を学習できます。
個々の CRUD 操作には、関連する メソッドを使用できます。 たとえば、1 つのドキュメントを挿入して複数のドキュメントを更新するには、 insertOne()
メソッドとupdateMany()
メソッドを使用できます。
MongoClient
は、各操作に対応するデータベースにリクエストを送信し、これらの操作を実行します。 一括操作を使用することで、データベースへの呼び出し回数を減らすことができます。
一括操作の実行
一括操作は、多数の書込み (write) 操作で構成されています。 一括操作を実行するには、 WriteModel
List
をbulkWrite()
メソッドに渡します。 WriteModel
は、単一の書込み操作を表すモデルです。
次のセクションでは、 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( 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
の値が1
と3
である 2 つのドキュメントを挿入しようとしています。 コレクションには_id
が1
であるドキュメントがすでにあるため、操作はエラーになります。
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
を含むドキュメントを挿入しなかった理由については、「実行順序 」セクションを参照してください。
置換操作
置換操作を実行するには、置換するドキュメントと置換ドキュメントのクエリフィルターを指定するReplaceOneModel
を作成します。
重要
bulkWrite()
を実行する場合、 ReplaceOneModel
はコレクションの一意のインデックス制約に違反する変更を行うことはできません。 さらに、クエリフィルターに一致するものがない場合、モデルは置換操作を実行しません。
例
次の例では、 ReplaceOneModel
を作成して、 _id
が1
であるドキュメントを、追加のlocation
フィールドを含むドキュメントに置き換えます。
val filter = Filters.eq("_id", 1) val insert = Person(1, "Celine Stork", location = "San Diego, CA") val doc = ReplaceOneModel(filter, insert)
このセクションで述べられたメソッドとクラスの詳細については、次のリソースを参照してください。
ReplaceOneModel API ドキュメント
一意なインデックスサーバー マニュアルの説明
アップデート操作
アップデート操作を実行するには、クエリフィルターとアップデート ドキュメントを指定するUpdateOneModel
またはUpdateManyModel
を作成します。
UpdateOneModel
はクエリフィルターに一致する最初のドキュメントを更新し、 UpdateManyModel
はクエリフィルターに一致するすべてのドキュメントを更新します。
重要
bulkWrite()
を実行する場合、 UpdateOneModel
型とUpdateManyModel
型はコレクションの一意のインデックス制約に違反する変更を行うことはできません。 さらに、クエリフィルターに一致するものがない場合、モデルは更新操作を実行しません。
例
次の例では、 _id
が2
であるドキュメントでage
フィールドを1
ずつ増加させるためのUpdateOneModel
を作成します。
val filter = Filters.eq("_id", 2) val update = Updates.inc(Person::age.name, 1) val doc = UpdateOneModel<Person>(filter, update)
このセクションで述べられたメソッドとクラスの詳細については、次のリソースを参照してください。
UpdateOneModel API Documentation
UpdateManyModel API ドキュメント
一意なインデックスサーバー マニュアルの説明
削除操作
削除操作を実行するには、削除するドキュメントのクエリフィルターを指定するDeleteOneModel
またはDeleteManyModel
を作成します。
DeleteOneModel
はクエリフィルターに一致する最初のドキュメントを削除し、 DeleteManyModel
はクエリフィルターに一致するすべてのドキュメントを削除します。
重要
bulkWrite()
の実行時に、クエリフィルターに一致しない場合、 DeleteOneModel
およびDeleteManyModel
タイプはドキュメントを削除しません。
例
次の例では、 _id
が1
であるドキュメントを削除するための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"
で、age
が37
であるドキュメントの挿入操作_id
が1
であるドキュメントを、location
フィールドを含む新しいドキュメントに置き換え操作_id
が6
であるドキュメントの更新操作で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 ドキュメントを参照してください。
概要
一括操作を実行するには、作成してWriteModel
ドキュメントのリストをbulkWrite()
メソッドに渡します。
WriteModel
には 6 つのバリエーションがあります。
InsertOneModel
ReplaceOneModel
UpdateOneModel
UpdateManyModel
DeleteOneModel
DeleteManyModel
bulkWrite()
メソッドを実行するには次の 2 つの方法があります。
順序付き。エラーが発生するまで、ドライバーは書込み操作を順番に実行します。
順序付けなし: ドライバーがすべての書込み (write) 操作を任意の順序で実行し、操作の完了後にエラーを報告します。