Overview
このガイドでは、Rust ドライバーを使用して、カーソルを使用して読み取り操作または集計から返されたデータにアクセスする方法を学習します。 カーソルは、特定の時点でメモリ内にドキュメントのサブセットのみを保持しながら、複数のドキュメントを反復処理できるメカニズムです。
ドライバーは、カーソルからドキュメントを検索するためのCursorタイプを提供します。 たとえば、複数のドキュメントを返すことができる検索操作を実行すると、ドライバーはCursorインスタンスを返し、そこから一致したドキュメントにアクセスできます。
読み取り操作または集計を実行すると、返されるCursorインスタンスに操作結果の最初のバッチが含まれます。 カーソルを反復処理すると、サーバーはより個別の結果を返します。 結果のバッチの末尾に到達した後に一致するドキュメントがさらにある場合、すべての結果が返されるまで、 Cursorインスタンスは次のドキュメントのバッチを取得します。
このガイドには、次のセクションが含まれています。
例のサンプル データは、カーソルの例で使用されるサンプル データを示します
配列としてのドキュメントを取得では、返されたカーソル結果を収集して、すべての結果を単一の配列としてアクセスする方法について説明します。
未加工ドキュメントバッチの検索 では、BSONデータに直接アクセスしてゼロコピー ドキュメント プロセシングを行うための未加工バッチするカーソルAPIの使用方法について説明します。
カーソルの動作を指定するでは、メソッドが返すカーソルを構成する方法について説明します。
追加情報では、このガイドで言及されている型とメソッドのリソースとAPIドキュメントへのリンクを提供します
サンプルデータの例
このガイドの例では、 構造体に保存されている次のデータを使用します。
let docs = vec! [ Fruit { name: "strawberry".to_string(), color: "red".to_string() }, Fruit { name: "banana".to_string(), color: "yellow".to_string() }, Fruit { name: "pomegranate".to_string(), color: "red".to_string() }, Fruit { name: "pineapple".to_string(), color: "yellow".to_string() } ];
ドキュメントを個別に検索する
このドライバーは、 Cursorインスタンスによって返されたドキュメントを反復処理するための次のアクセス パターンを提供します。
組み込みパターン: カーソルを進み、現在のドキュメントを検索して逆直列化します
ストリーム実装パターン: カーソルを反復処理し、
Streamが提供するメソッドを呼び出して、単一または複数のドキュメントを処理
次のセクションでは、これらのアクセス パターンと対応するメソッドについて詳しく説明します。
組み込みパターン
ドライバーに組み込まれているアクセス パターンを使用して、ドキュメントを 1 つずつ検索して処理できます。
Cursorタイプには、カーソルを反復処理してドキュメントに個別にアクセスするためのadvance() deserialize_current()メソッドと メソッドが含まれています。
advance()メソッドはカーソルを転送し、ローカル バッファが使い果たされたときにデータベースに詳細な結果を送信します。これはカーソルが結果のバッチの末尾に到達したときに発生します。 カーソルが結果のバッチの末尾に到達するたびに、次のバッチをリクエストします。 カーソルは、返される一致するドキュメントがなくなり、使用できなくなると使い果たされます。 advance()メソッドは、新しい結果が正常に返された場合はtrueの結果を返し、カーソルが閉じられた場合はfalseの結果を返します。
deserialize_current()メソッドは、カーソル内の現在の結果への参照を返し、その結果をカーソルに関連付けられた型に逆直列化します。 型を指定しない限り、メソッドはコレクションが パラメーター化されている型と同じ型を使用します。
重要
advance()メソッドがtrueの結果を返す場合にのみ、 deserialize_current()メソッドを呼び出すことができます。 true結果なしで、または以前にadvance()を呼び出しずにカーソルでdeserialize_current()を呼び出すと、ドライバーはエラーを生成します。
次の例は、このアクセス パターンを実装して、 fruitsコレクションでの検索操作の結果を反復処理する方法を示しています。
let mut cursor = my_coll.find(doc! { "color": "red" }).await?; while cursor.advance().await? { println!("{:?}", cursor.deserialize_current()?); }
Fruit { name: "strawberry", color: "red" } Fruit { name: "pomegranate", color: "red" }
ストリーム実装パターン
ストリームとしてカーソル結果にアクセスして、個々のドキュメントを取得したり、複数のドキュメントを一度に収集したりできます。
Cursor型はStream特権を実装しているため、ストリームとしてカーソルを反復処理できます。 このパターンを使用すると、組み込みパターンよりも簡潔なコードを記述できます。 StreamExt Stream拡張機能は、操作を組み合わせてコードを統合するための多数の機能を提供するためです。
ストリーム パターンを使用するには、次のメソッドを使用できます。
next(): カーソルを次の結果に進め、Option<Result<T>>タイプを返しますtry_next(): カーソルを次の結果に進め、Result<Option<T>>タイプを返します
重要
ストリーム パターン メソッドに必要なインポート
next()メソッドを使用するには、 StreamExt特性をインポートする必要があります。 try_next()メソッドを使用するには、 TryStreamExt特性をインポートする必要があります。
次の例は、2 つのストリーム メソッドを実装して、 fruitsコレクションでの検索操作の結果を反復処理する方法を示しています。
let mut cursor = my_coll.find(doc! { "color": "red" }).await?; println!("Output from next() iteration:"); while let Some(doc) = cursor.next().await { println!("{:?}", doc?); } println!(); let mut cursor = my_coll.find(doc! { "color": "yellow" }).await?; println!("Output from try_next() iteration:"); while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Output from next() iteration: Fruit { name: "strawberry", color: "red" } Fruit { name: "pomegranate", color: "red" } Output from try_next() iteration: Fruit { name: "banana", color: "yellow" } Fruit { name: "pineapple", color: "yellow" }
ドキュメントを配列として取得
Cursor型はStream特権を実装しているため、カーソルからの結果を配列に収集できます。
ドキュメントを配列として取得するには、次のメソッドを使用します。
collect(): カーソルからの結果をVec<Result<T>>型に収集しますtry_collect(): カーソルからの結果をResult<Vec<T>>型に収集します
注意
collect()メソッドを使用するには、 StreamExt特性をインポートする必要があります。 try_collect()メソッドを使用するには、 TryStreamExt特性をインポートする必要があります。
let cursor = my_coll.find(doc! { "color": "red" }).await?; println!("Output from collect():"); let v: Vec<Result<Fruit>> = cursor.collect().await; println!("{:?}", v); println!(); let cursor = my_coll.find(doc! { "color": "yellow" }).await?; println!("Output from try_collect():"); let v: Vec<Fruit> = cursor.try_collect().await?; println!("{:?}", v);
Output from collect(): [Ok(Fruit { name: "strawberry", color: "red" }), Ok(Fruit { name: "pomegranate", color: "red" })] Output from try_collect(): [Fruit { name: "banana", color: "yellow" }, Fruit { name: "pineapple", color: "yellow" }]
警告
アプリケーション メモリ制限の超過を避ける
大規模な結果を配列に変換する ことは避けてください 。 配列が使用可能なアプリケーション メモリのサイズを超えると、アプリケーションがクラッシュする可能性があります。 大規模な結果セットが予想される場合は、カーソルからドキュメントを個別に検索してください。 カーソルを反復処理する方法については、このガイドの「 ドキュメントを個別に取得する 」セクションを参照してください。
Raw バッチするカーソルの使用
find() などのカーソルを返す操作で batch() メソッドを呼び出して RawBatchCursor を返すことができます。これにより、シリアル化された個々の値ではなく、サーバーによって返された未加工BSONドキュメントをバッチする単位で反復処理できます。このモジュールは、サーバー応答バッチへの直接アクセスが必要な場合にドキュメントを処理する高パフォーマンスの方法を提供します。高スループットを持つパフォーマンスを重視したカーソル アプリケーションには、rawバッチするモードを使用します。
Raw バッチするプロセシングの例
未加工のバッチするカーソルAPI を使用するには、カーソルを返す操作で batch() メソッドを呼び出して、通常の Cursor ではなく RawBatchCursor を返します。その後、バッチするを繰り返し処理し、各バッチする内の個々のドキュメントにアクセスできます。
次の例は、未加工のバッチするカーソルを使用してドキュメントを処理する方法を示しています。
let mut cursor = my_coll.find(doc! { "color": "red" }).batch().await?; while let Some(batch) = cursor.next().await { let batch = batch?; let doc_slices = batch.doc_slices()?; let count = doc_slices.into_iter().count(); println!("Processing batch with {} documents", count); for doc_result in batch.doc_slices()? { let doc = doc_result?; if let mongodb::bson::RawBsonRef::Document(raw_doc) = doc { println!("Raw document size: {} bytes", raw_doc.as_bytes().len()); } } }
Processing batch with 4 documents Raw document size: 58 bytes Raw document size: 59 bytes Raw document size: 58 bytes Raw document size: 59 bytes
raw_バッチする_カーソル_APIについて詳しく学ぶには、APIドキュメントのページをご覧ください。
カーソルの動作を指定する
操作によって返されるカーソルを変更するには、 Cursorインスタンスを返すメソッドにオプション ビルダ メソッドを連結します。 たとえば、カーソル関連のオプション ビルダのメソッドをfind()メソッドに連鎖させることができます。
注意
設定オプション
オプション ビルダのメソッドをfind()メソッド呼び出しに直接連鎖させることで、 FindOptionsフィールドを設定できます。 以前のバージョンのドライバーを使用している場合は、オプション ビルダー メソッドをbuilder()メソッドに連結してFindOptionsインスタンスを構築する必要があります。 次に、 FindOptionsインスタンスをfind()のパラメータとして渡します。
次の表では、対応するビルダ メソッドを呼び出して設定できるカーソル関連のオプションについて説明します。
設定 | 説明 |
|---|---|
| カーソルバッチごとにサーバーが返すドキュメントの最大数を指定します。このオプションは、カーソルが返すドキュメントの数ではなく、カーソルがメモリに保持するドキュメントの数を設定します。 |
| 返すカーソルの種類を指定します。このオプションを設定して、追尾可能 (tailable) カーソルを生成できます。追尾可能 (tailable) カーソルの詳細については、サーバーマニュアルの「追尾可能 (tailable) カーソル」を参照してください。 |
| サーバーが一定期間の非アクティビティの後にカーソルを閉じるかどうかを指定します。 タイプ: |
次のコードは、オプション ビルダー メソッドをfind()メソッドに連鎖させて、カーソル関連の設定を指定する方法を示しています。
let mut cursor = my_coll.find(doc! { "color": "red" }) .batch_size(5) .cursor_type(CursorType::Tailable) .no_cursor_timeout(true) .await?;
詳細情報
このガイドの操作の詳細については、次のドキュメントを参照してください。
ドキュメントの検索ガイド
Rust 型と BSON の変換の詳細については、「データ モデリングと直列化 」に関するガイドを参照してください。
API ドキュメント
このガイドで言及されているメソッドとタイプの詳細については、次のAPIドキュメントを参照してください。
特権の next()
StreamExt特権のtry_next()
TryStreamExt特権の collection()
StreamExt特権のtry_collection()
TryStreamExt