Overview
このガイドでは、Rust ドライバーを使用して一括操作を実行する方法を学習できます。
一括操作は、1 つ以上の名前空間に対して複数の書込み操作を実行します。 名前空間は、データベース名とコレクション名の組み合わせで、形式は<database>.<collection>です。 Clientインスタンスで一括操作を実行するため、クライアントがアクセスするクラスター内の任意の名前空間に対して一括操作を実行できます。
一括操作を実行して、サーバーへの呼び出し回数を減らすことができます。 一括操作では、各操作のリクエストを送信する代わりに、1 つのアクション内に複数の操作を実行します。
このガイドには、次のセクションが含まれています。
サンプル データは、一括操作の例で使用されるサンプル データを提供します
一括操作タイプでは、
WriteModelタイプを使用して一括挿入、置換、アップデート、削除操作を実行する方法について説明します戻り値の型は、
bulk_write()メソッドの戻り値と、一括操作に関する情報にアクセスする方法を示します「動作の変更」では、
bulk_write()メソッドのデフォルトの動作を変更する方法について説明します。混合名前空間への書き込みでは、1 回のメソッド呼び出しで複数の名前空間に対して一括操作を実行する方法について説明します
追加情報では、このガイドで言及されている型とメソッドのリソースとAPIドキュメントへのリンクを提供します
重要
一括書き込み操作を実行するには、アプリケーションが次の要件を満たしていることを確認してください。
MongoDB Server バージョン8.0以降に接続している場合
Rust ドライバー バージョン3.0以降を使用している。
サンプル データ
このガイドの例では、 dbデータベースのmushroomsコレクションに保存されている次のサンプル ドキュメントを使用します。
let docs = vec![ doc! {"name" : "portobello", "color" : "brown", "edible" : true }, doc! {"name" : "chanterelle", "color" : "yellow", "edible" : true }, doc! {"name" : "oyster", "color" : "white", "edible" : true }, doc! {"name" : "fly agaric", "color" : "red", "edible" : false }, ];
カスタム構造体 を使用してサンプル データを表すこともできます。 Mushroom構造体を使用して同じデータをモデル化して一括操作を実行する例については、このページの「 構造体の挿入の例」を参照してください。
一括操作のタイプ
一括書き込み操作を実行するには、 WriteModel列挙インスタンスの配列をbulk_write()メソッドに渡します。
このセクションでは、対応するWriteModelタイプを定義することで、次の一括書き込み操作を実行する方法を説明します。
Tip
単一のbulk_write()メソッド呼び出しで複数のタイプの書込み操作を実行することもできます。 UpdateOneModelとInsertOneModelを同じbulk_write()呼び出しに渡す例については、このガイドの「動作の変更 」の例を参照してください。
Insert
一括挿入操作を実行するには、挿入するドキュメントごとにInsertOneModelインスタンスを作成します。 次に、モデルのリストをbulk_write()メソッドに渡します。
次の表では、対応するビルダー メソッドを呼び出して設定できるInsertOneModelフィールドについて説明しています。
フィールド | 説明 |
|---|---|
|
|
| 挿入するドキュメント。 |
ドキュメントの挿入の例
この例では、次のアクションを実行します。
配列内の 2 つの
InsertOneModelインスタンスを指定します。 各InsertOneModelは、db.mushrooms名前空間に挿入するドキュメントを表します。モデルの配列を
bulk_write()メソッドに渡します。挿入されたドキュメントの数を出力します。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "lion's mane", "color": "white", "edible": true }) .build(), InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "angel wing", "color": "white", "edible": false }) .build(), ]; let result = client.bulk_write(models).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
構造体を挿入した例
また、 構造体 と 構造体インスタンスをdb.mushrooms名前空間に一括挿入して、ドキュメントをモデル化することもできます。
この例では、前述のドキュメントの挿入の例と同じ操作を実行しますが、次のMushroom構造体型のインスタンスを挿入します。
struct Mushroom { name: String, color: String, edible: bool, }
次のコードでは、 insert_one_model()メソッドを使用して各MushroomインスタンスからInsertOneModelを構築し、両方のモデルを一括操作で挿入します。
let mushrooms: Collection<Mushroom> = client.database("db").collection("mushrooms"); let lions_mane = Mushroom { name: "lion's mane".to_string(), color: "white".to_string(), edible: true, }; let angel_wing = Mushroom { name: "angel wing".to_string(), color: "white".to_string(), edible: false, }; let lions_mane_model = mushrooms.insert_one_model(lions_mane)?; let angel_wing_model = mushrooms.insert_one_model(angel_wing)?; let result = client.bulk_write([lions_mane_model, angel_wing_model]).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
Tip
Rust ドライバーのカスタム構造体型と直列化の詳細については、「データ モデリングと直列化 」に関するガイドを参照してください。
置換
一括置換操作を実行するには、置き換えるドキュメントごとにReplaceOneModelインスタンスを作成します。 次に、モデルのリストをbulk_write()メソッドに渡します。
次の表では、対応するビルダー メソッドを呼び出して設定できるReplaceOneModelフィールドについて説明しています。
フィールド | 説明 |
|---|---|
|
|
| 置き換えるドキュメントに一致するフィルター。 |
| 置換ドキュメントです。 |
| |
| (任意)操作に使用するインデックス。インデックスの詳細については、「 インデックスガイド |
| (任意) フィルター に一致するドキュメントがない場合に新しいドキュメントを作成するかどうか。 |
例
この例では、次のアクションを実行します。
配列内の 2 つの
ReplaceOneModelインスタンスを指定します。ReplaceOneModelインスタンスには、db.mushrooms名前空間内のきのこのドキュメントを置き換えるための指示が含まれています。モデルの配列を
bulk_write()メソッドに渡します。変更されたドキュメントの数を出力します。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ ReplaceOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "portobello" }) .replacement(doc! { "name": "cremini", "color": "brown", "edible": true }) .build(), ReplaceOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "oyster" }) .replacement(doc! { "name": "golden oyster", "color": "yellow", "edible": true }) .upsert(true) .build(), ]; let result = client.bulk_write(models).await?; println!("Modified documents: {}", result.modified_count);
Modified documents: 2
Update
一括更新操作を実行するには、実行する更新ごとにUpdateOneModelまたはUpdateManyModelインスタンスを作成します。 次に、モデルのリストをbulk_write()メソッドに渡します。 UpdateOneModelはフィルターに一致するドキュメントを 1 つだけ更新し、 UpdateManyModelはフィルターに一致するすべてのドキュメントを更新します。
次の表では、対応するビルダーUpdateOneModel UpdateManyModelメソッドを呼び出して設定できる フィールドと フィールドについて説明しています。
フィールド | 説明 |
|---|---|
|
|
| 更新する 1 つ以上のドキュメントに一致するフィルター。 |
| 実行される更新。 |
| (任意) 配列値フィールドを更新する場合に更新を適用する配列要素を指定するフィルターのセット。 |
| |
| (任意)操作に使用するインデックス。インデックスの詳細については、「 インデックスガイド |
| (任意) フィルター に一致するドキュメントがない場合に新しいドキュメントを作成するかどうか。デフォルトでは、このフィールドは |
例
この例では、次のアクションを実行します。
配列で インスタンスと
UpdateOneModelUpdateManyModelインスタンスを指定します。これらのモデルには、db.mushrooms名前空間内のシノニムを表すドキュメントを更新するための指示が含まれています。モデルの配列を
bulk_write()メソッドに渡します。変更されたドキュメントの数を出力します。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::UpdateOne( UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "fly agaric" }) .update(doc! { "$set": { "name": "fly amanita" } }) .upsert(true) .build(), ), WriteModel::UpdateMany( UpdateManyModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "color": "yellow" }) .update(doc! { "$set": { "color": "yellow/orange" } }) .build(), ), ]; let result = client.bulk_write(models).await?; println!("Modified documents: {}", result.modified_count);
Modified documents: 2
削除
一括削除操作を実行するには、削除操作ごとにDeleteOneModelまたはDeleteManyModelインスタンスを作成します。 次に、モデルのリストをbulk_write()メソッドに渡します。 DeleteOneModelはフィルターに一致するドキュメントを 1 つだけ削除し、 DeleteManyModelはフィルターに一致するすべてのドキュメントを削除します。
次の表では、対応するビルダーDeleteOneModel DeleteManyModelメソッドを呼び出して設定できる フィールドと フィールドについて説明しています。
フィールド | 説明 |
|---|---|
|
|
| 削除したい 1 つ以上のドキュメントに一致するフィルター。 |
| |
| (任意)操作に使用するインデックス。インデックスの詳細については、「 インデックスガイド |
例
この例では、次のアクションを実行します。
配列で インスタンスと
DeleteOneModelDeleteManyModelインスタンスを指定します。これらのモデルには、db.mushrooms名前空間内のシノニムを表すドキュメントを削除するための手順が含まれています。モデルの配列を
bulk_write()メソッドに渡します。削除されたドキュメントの数を出力します。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::DeleteOne( DeleteOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "color": "red" }) .build(), ), WriteModel::DeleteMany( DeleteManyModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "edible": true }) .build(), ), ]; let result = client.bulk_write(models).await?; println!("Deleted documents: {}", result.deleted_count);
Deleted documents: 4
戻り値の型
bulk_write()メソッドは、一括操作に関する情報にアクセスできるSummaryBulkWriteResult構造体インスタンスを返します。
SummaryBulkWriteResult型には次のフィールドがあります。
inserted_count: 挿入されたドキュメントの数matched_count: 一致したドキュメントの数modified_count: 更新されたドキュメントの数upserted_count: アップサートされた文書の数deleted_count: 削除されたドキュメントの数
また、 verbose_results()メソッドを使用して、各操作に関する詳細情報を表示することもできます。 verbose_results()メソッドは、次のフィールドを持つVerboseBulkWriteResult構造体インスタンスを返します。
delete_results: 成功した各削除操作の結果insert_results: 成功した各挿入操作の結果update_results: 成功した各更新操作の結果summary: 各操作タイプの結果の概要
次の例では、 verbose_results()メソッドをbulk_write()メソッドに連結し、アップデート操作と削除操作の結果を出力します。
let models = vec![ WriteModel::DeleteOne( DeleteOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "oyster" }) .build(), ), WriteModel::UpdateOne( UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "chanterelle" }) .update(doc! { "$set": { "season": ["July", "August", "September"] } }) .build(), ), ]; let result = client.bulk_write(models).verbose_results().await?; println!( "Update results: {:?}\nDelete results: {:?}\n", result.update_results, result.delete_results );
Update results: {1: UpdateResult { matched_count: 1, modified_count: 1, upserted_id: None }} Delete results: {0: DeleteResult { deleted_count: 1 }}
動作の変更
BulkWriteOptionsフィールド値を設定することで、 bulk_write()メソッドの動作を変更できます。 これらの構造体フィールドを設定するには、フィールドに対応するメソッドをbulk_write()メソッドに連鎖させます。
BulkWriteOptions構造体には次のフィールドが含まれています。
フィールド | 説明 | デフォルト値 |
|---|---|---|
| 操作が指定された順序で実行されるかどうか。 |
|
|
|
|
| データベースプロファイラ、currentOp、およびログから操作を追跡するのに役立つ任意のコメント。タイプ: |
|
|
|
|
| この 一括操作に使用する書込み保証 (write | 名前空間の書込み保証 (write concern) を継承します |
例
この例では、 mushroomsコレクションに対してアップデート操作と挿入操作を実行しようとしています。 次のコードでは、 ordered()メソッドをbulk_write()メソッドに連結して、 orderedフィールドをfalseに設定します。
let mushrooms: Collection<Document> = client.database("db").collection("mushrooms"); let models = vec![ WriteModel::UpdateOne(UpdateOneModel::builder() .namespace(mushrooms.namespace()) .filter(doc! { "name": "portobello" }) .update(doc! { "$set": { "_id": 123 } }) .upsert(true) .build()), WriteModel::InsertOne(InsertOneModel::builder() .namespace(mushrooms.namespace()) .document(doc! { "name": "reishi", "color": "red/brown", "edible": true }) .build()), ]; let result = client.bulk_write(models).ordered(false).await?; println!( "Inserted documents: {}\nDeleted documents: {}", result.inserted_count, result.deleted_count );
Error: Error { kind: BulkWrite(BulkWriteError { write_concern_errors: [], write_errors: {0: WriteError { code: 66, code_name: None, message: "Plan executor error during update :: caused by :: Performing an update on the path '_id' would modify the immutable field '_id'", details: None }}, partial_result: Some(Summary(SummaryBulkWriteResult { inserted_count: 1, matched_count: 0, modified_count: 0, upserted_count: 0, deleted_count: 0 })) }), labels: ... }
_idフィールドは不変であり、更新操作では変更できません。 UpdateOneModelにはこのフィールドをアップデートするための指示が含まれているため、一括操作はBulkWriteErrorを返し、挿入操作のみを実行します。 orderedフィールドをtrueに設定すると、ドライバーは失敗した更新操作後に後続の操作を試行せず、ドキュメントを挿入しません。
混合名前空間への書込み
このページの前述の例では、 db.mushrooms名前空間に対して一括操作を実行しています。 ただし、1 回のメソッド呼び出しで複数の名前空間に対して一括書き込みを実行できます。
次の例では、 ingredients.sweet名前空間に 1 つのドキュメントを挿入し、 meals.dessert名前空間に 2 つのドキュメントを挿入します。
let sweet: Collection<Document> = client .database("ingredients") .collection("sweet"); let dessert: Collection<Document> = client .database("meals") .collection("dessert"); let models = vec![ InsertOneModel::builder() .namespace(sweet.namespace()) .document(doc! { "name": "brown sugar", "price": 3.99 }) .build(), InsertOneModel::builder() .namespace(dessert.namespace()) .document(doc! { "name": "banana bread", "cook_time": 75 }) .build(), ]; let result = client.bulk_write(models).await?; println!("Inserted documents: {}", result.inserted_count);
Inserted documents: 2
詳細情報
一括操作の詳細については、サーバー マニュアルの「一括書込み操作」を参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。