Docs Menu
Docs Home
/ / /
Rust ドライバー
/ / /

一括操作

項目一覧

  • Overview
  • サンプル データ
  • 一括操作のタイプ
  • Insert
  • 置換
  • Update
  • 削除
  • 戻り値の型
  • 動作の変更
  • 混合名前空間への書込み
  • 詳細情報

このガイドでは、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()メソッド呼び出しで複数のタイプの書込み操作を実行することもできます。 UpdateOneModelInsertOneModelを同じbulk_write()呼び出しに渡す例については、このガイドの「動作の変更 」の例を参照してください。

一括挿入操作を実行するには、挿入するドキュメントごとにInsertOneModelインスタンスを作成します。 次に、モデルのリストをbulk_write()メソッドに渡します。

次の表では、対応するビルダー メソッドを呼び出して設定できるInsertOneModelフィールドについて説明しています。

フィールド
説明

namespace

The namespace on which the insert is performed.
Type: Namespace

document

The document to insert.
Type: Document

この例では、次のアクションを実行します。

  • 配列内の 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構造体型のインスタンスを挿入します。

#[derive(Serialize)]
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フィールドについて説明しています。

フィールド
説明

namespace

The namespace on which the operation is performed.
Type: Namespace

filter

The filter that matches the document you want to replace.
Type: Document

replacement

The replacement document.
Type: Document

collation

(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document

hint

(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson

upsert

(Optional) Whether a new document is created if no document matches the filter.
By default, this field is set to false.
Type: bool

この例では、次のアクションを実行します。

  • 配列内の 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

一括更新操作を実行するには、実行する更新ごとにUpdateOneModelまたはUpdateManyModelインスタンスを作成します。 次に、モデルのリストをbulk_write()メソッドに渡します。 UpdateOneModelはフィルターに一致するドキュメントを 1 つだけ更新し、 UpdateManyModelはフィルターに一致するすべてのドキュメントを更新します。

次の表では、対応するビルダーUpdateOneModel UpdateManyModelメソッドを呼び出して設定できる フィールドと フィールドについて説明しています。

フィールド
説明

namespace

The namespace on which the operation is performed.
Type: Namespace

filter

The filter that matches one or more documents you want to update. When specified in an UpdateOneModel, only the first matching document will be updated. When specified in an UpdateManyModel, all matching documents will be updated.
Type: Document

update

The update to perform.
Type: UpdateModifications

array_filters

(Optional) A set of filters specifying which array elements an update applies to if you are updating an array-valued field.
Type: Array

collation

(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document

hint

(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson

upsert

(Optional) Whether a new document is created if no document matches the filter. By default, this field is set to false.
Type: bool

この例では、次のアクションを実行します。

  • 配列で インスタンスとUpdateOneModel UpdateManyModelインスタンスを指定します。これらのモデルには、 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メソッドを呼び出して設定できる フィールドと フィールドについて説明しています。

フィールド
説明

namespace

The namespace on which the operation is performed.
Type: Namespace

filter

The filter that matches one or more documents you want to delete. When specified in a DeleteOneModel, only the first matching document will be deleted. When specified in a DeleteManyModel, all matching documents will be deleted.
Type: Document

collation

(Optional) The collation to use when sorting results. To learn more about collations, see the Collations guide.
Type: Document

hint

(Optional) The index to use for the operation. To learn more about indexes, see the Indexes guide.
Type: Bson

この例では、次のアクションを実行します。

  • 配列で インスタンスとDeleteOneModel DeleteManyModelインスタンスを指定します。これらのモデルには、 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構造体には次のフィールドが含まれています。

フィールド
説明
デフォルト値

ordered

Whether the operations run in the order in which they were specified.
When set to true, one failed operation prevents subsequent operations from running.
When set to false, the server continues to attempt write operations if one fails.
Type: bool

true

bypass_document_validation

Whether document-level validation is bypassed.
Type: bool

false

comment

An arbitrary comment to help trace the operation through the database profiler, currentOp, and logs.
Type: Bson

None

let_vars

A map of parameter names and values to apply to all operations within the bulk write. Values must be constant or closed expressions that do not reference document fields.
Type: Document

None

write_concern

The write concern to use for this bulk operation.
Type: WriteConcern

名前空間の書込み保証 (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

一括操作の詳細については、サーバー マニュアルの「一括書込み操作」を参照してください。

戻る

削除