カーソルからデータにアクセスする
Overview
複数のドキュメントを返す読み取り操作では、クエリに一致するすべての値がすぐに返されるわけではありません。クエリは非常に大きなドキュメントセットと一致する可能性があるため、これらの操作はカーソルと呼ばれるオブジェクトを返します。カーソルは、クエリで識別されたドキュメントを参照します。カーソルはドキュメントをバッチで取得して、メモリ消費とネットワーク帯域幅使用量の両方を削減します。カーソルは高度な構成が可能で、さまざまなユースケースに対応する複数のインタラクションパラダイムを提供します。
次の関数を使用することで、カーソルを直接返せます。
Collection.find()
Collection.aggregate()
Collection.listIndexes()
Collection.listSearchIndexes()
Db.aggregate()
Db.listCollections()
などの他のメソッドでは、 Collection.findOne()やCollection.watch()が 内部的にカーソルが使用され、カーソルの代わりに操作の結果が返されます。
カーソル パラダイム
データへのアクセスには、いくつかの異なるカーソル パラダイムを使用できます。ほとんどのカーソル パラダイムでは、一度に 1 ドキュメントずつクエリ結果にアクセスできるため、ネットワークとキャッシュ ロジックが抽象化されます。ただし、ユースケースは異なるため、一致するドキュメントをすべてプロセスメモリ内のコレクションに取り込むなど、他のパラダイムではアクセス パターンが異なります。
警告
1 つのカーソル上で異なるカーソル パラダイムを組み合わせないでください。hasNext()
や toArray()
などの操作はそれぞれ、元のカーソルを予想どおりに変更します。これらの呼び出しを 1 つのカーソルで混在させると、予期しない結果が生じる可能性があります。
警告
非同期呼び出しはカーソルを直接変更するため、1 つのカーソルで非同期呼び出しを同時に実行すると、未定義の動作が発生する可能性もあります。必ず前の非同期操作が完了するのを待ってから、次の非同期操作を実行してください。
注意
反復処理または一括フェッチによって最後の結果に到達すると、カーソルが使い果たされ、結果にアクセスするメソッドに応答しなくなります。
非同期反復
カーソルはAsyncIteratorインターフェースを実装し、for await...of
ループでカーソルを使用できます。
const cursor = myColl.find({}); console.log("async"); for await (const doc of cursor) { console.log(doc); }
手動反復
hasNext() メソッドを使用して、カーソルがさらにデータを取得できるかどうかを確認し、次に next() メソッドを使用して、カーソルの次の要素を取得します。
const cursor = myColl.find({}); while (await cursor.hasNext()) { console.log(await cursor.next()); }
すべてのドキュメントの配列を返す
クエリに一致するすべてのドキュメントを同時にメモリに保持する必要があるユースケースの場合は、 toArray() 使用して複数のドキュメントを挿入できます。操作がメモリ制約を超えると、一致したドキュメントが多数あるとパフォーマンスの問題や失敗が発生する可能性があることに注意してください。 すべてのドキュメントを一度に返すのではなく、 for await...of
構文を使用して結果を反復処理することを検討してください。
const cursor = myColl.find({}); const allValues = await cursor.toArray();
ストリーム API
カーソルは、ノード読み取り可能ストリームに変換するための stream()
メソッドを公開します。これらのストリームは オブジェクト モードで 動作し、バッファーや文字列ではなく JavaScript オブジェクトをパイプラインに渡します。
const cursor = myColl.find({}); cursor.stream().on("data", doc => console.log(doc));
イベント API
読み取り可能なストリームとして、カーソルは Event API の close
、 data
、 end
、および readable
イベントもサポートしています。
const cursor = myColl.find({}); // the "data" event is fired once per document cursor.on("data", data => console.log(data));
カーソル ユーティリティー メソッド
巻き戻す
返されたドキュメントのセット内のカーソルを最初の位置にリセットするには、 rewind() を使用します。
const cursor = myColl.find({}); const firstResult = await cursor.toArray(); console.log("First count: " + firstResult.length); await cursor.rewind(); const secondResult = await cursor.toArray(); console.log("Second count: " + secondResult.length);
閉じる
カーソルは、クライアント アプリケーションと MongoDB の接続インスタンスの両方でメモリーとネットワーク リソースを消費します。close() を使用して、クライアント アプリケーションと MongoDB サーバーの両方でカーソルのリソースを解放します。
await cursor.close();