AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。

カーソルからデータにアクセスする

複数のドキュメントを返す読み取り操作では、クエリに一致するすべての値がすぐに返されるわけではありません。クエリは非常に大きなドキュメントセットと一致する可能性があるため、これらの操作はカーソルと呼ばれるオブジェクトを返します。カーソルは、クエリで識別されたドキュメントを参照します。カーソルはドキュメントをバッチで取得して、メモリ消費とネットワーク帯域幅使用量の両方を削減します。カーソルは高度な構成が可能で、さまざまなユースケースに対応する複数のインタラクションパラダイムを提供します。

次の関数を使用することで、カーソルを直接返せます。

  • 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();

カーソルは、ノード読み取り可能ストリームに変換するための stream() メソッドを公開します。これらのストリームは オブジェクト モードで 動作し、バッファーや文字列ではなく JavaScript オブジェクトをパイプラインに渡します。

const cursor = myColl.find({}); cursor.stream().on("data", doc => console.log(doc));

読み取り可能なストリームとして、カーソルは 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 Server の両方でカーソルのリソースを解放します。

await cursor.close();

リソースリークを防ぐために、アプリケーションが使用しなくなったカーソルを手動で閉じることをお勧めします。

Tip

明示的なリソース管理

Node.jsドライバーは、MongoClient、ClientSession、ChangeStreams、およびカーソルの明示的なリソース管理をネイティブでサポートしています。この機能は実験的なものであり、変更される可能性があります。明示的なリソース管理を使用する方法については、v6.9 リリースノートを参照してください。

中止シグナル を使用してカーソル操作をキャンセルできます。これにより、不要になった場合にカーソルによって使用されるメモリとネットワーク リソースを解放することで、リソースを管理するのに役立ちます。

注意

この機能は実験的です。シグナルを中止すると接続が閉じられ、不要な接続の再確立が発生する可能性があります。

signal コマンドを次のメソッドに渡すことができます。

  • collection.find()

  • collection.findOne()

  • collection.aggregate()

  • collection.countDocuments()

  • db.listCollections()

  • db.command()

中止信号を使用するには、AbortController インスタンスを作成し、コントローラーから signal を抽出します。このコード例では、プロセスは SIGINT(Ctrl+C)をリッスンして abort() メソッドをトリガーします。シグナルがトリガーされた場合にカーソル操作を中止するには、次の例に示すように、signal オプションを find() メソッドに渡すことができます。

const controller = new AbortController(); const { signal } = controller; process.on('SIGINT', () => controller.abort(new Error('^C pressed'))); try { const cursor = myColl.find({}, { signal }); for await (const doc of cursor) { console.log(doc); } } catch (error) { if (error === signal.reason) { console.error('Operation aborted:', error); } else { console.error('Unexpected error:', error); } }