db.collection.find()メソッドはカーソルを返します。ドキュメントにアクセスするには、カーソルを反復する必要があります。 ただし、 では、返されたカーソルがmongosh varキーワードを使用して変数に割り当てられていない場合、カーソルは自動的に最大20 回 []1 反復され、最初の20 まで出力されます。結果のドキュメント。
次の例で、カーソルを手動で反復処理してドキュメントにアクセスする方法や、イテレータ インデックスを使用する方法を説明します。
カーソルの手動反復処理
mongosh では、 find() メソッドから返されたカーソルを var キーワードを使用して変数に割り当てると、カーソルは自動的に反復されません。
以下の例のように、shell で cursor 変数を呼び出して、最大 20 回繰り返し [1]、一致するドキュメントを出力できます。
var myCursor = db.users.find( { type: 2 } ); myCursor
また、次の例のように、カーソル メソッド next() を使用してドキュメントにアクセスできます。
var myCursor = db.users.find( { type: 2 } ); while (myCursor.hasNext()) { print(tojson(myCursor.next())); }
代わりの出力操作として、printjson() ヘルパー メソッドを使用して print(tojson()) を置き換えることを検討してください。
var myCursor = db.users.find( { type: 2 } ); while (myCursor.hasNext()) { printjson(myCursor.next()); }
次の例のように、カーソル メソッド forEach() を使用してカーソルを反復処理し、ドキュメントにアクセスできます。
var myCursor = db.users.find( { type: 2 } ); myCursor.forEach(printjson);
カーソル メソッドの詳細については、「 JavaScript カーソル メソッド」およびドライバーのドキュメントを参照してください。
| [1] | (1、2)DBQuery.shellBatchSize 属性を設定して、ドキュメント数のデフォルト値 20 を変更できます。 |
イテレータ インデックス
mongosh では、次のように toArray() メソッドを使用してカーソルを反復処理し、ドキュメントを配列で返すことができます。
var myCursor = db.inventory.find( { type: 2 } ); var documentArray = myCursor.toArray(); var myDocument = documentArray[3];
toArray() メソッドは、カーソルによって返されたすべてのドキュメントを RAM にロードします。そのため、toArray() メソッドはカーソルを使い果たします。
さらに、一部のドライバーでは、カーソルのインデックス(つまり、cursor[index])を使用してドキュメントにアクセスできます。これは、最初に toArray() メソッドを呼び出し、次に結果の配列のインデックスを使用するショートカットです。
次の例で考えてみます。
var myCursor = db.users.find( { type: 2 } ); var myDocument = myCursor[1];
myCursor[1] は次の例と同等です。
myCursor.toArray() [1];
カーソルの動作
セッション内で開かれたカーソル
MongoDB 5.0 以降では、対応する クライアント セッション 内で作成されたカーソルは、セッションがタイムアウトした場合、またはクライアントがカーソルを使い果たした場合に、対応する サーバー セッション が killSessions コマンドで終了すると閉じます。
デフォルトでは、サーバー セッションの有効期限は 30 分です。この値を変更するには、mongod の起動時に localLogicalSessionTimeoutMinutes パラメータを設定します
セッション外で開かれたカーソル
セッション中に開かれていないカーソルは、 10分間操作がない場合、またはクライアントがカーソルを使い切ると自動的に閉じます。 mongoshでこの動作をオーバーライドするには、 cursor.noCursorTimeout()メソッドを使用します。
var myCursor = db.users.find().noCursorTimeout();
noCursorTimeout オプションの設定後は、cursor.close() を使用してカーソルを手動で閉じるか、カーソルの結果を使い切って閉じる必要があります。
noCursorTimeoutオプションの設定について詳しくは、ドライバーのドキュメント を参照してください。
カーソル使用中の同時更新
カーソルによってドキュメントが返されると、読み取り保証 (read concern)のレベルによっては、バックグラウンドで他の操作が実行され、結果に影響が出る可能性があります。 詳細については、「 読み取り分離、整合性、最新性について 」を参照してください。
カーソル バッチ
MongoDB サーバーはクエリ結果をバッチで返します。バッチ内のデータ量は、BSON ドキュメントの最大サイズ以下です。バッチのデフォルト サイズをオーバーライドするには、batchSize() および limit() を参照してください。
バージョン3.4の新機能: find() 、 aggregate() 、 listIndexes 、 listCollectionsの操作により、バッチするごとに最大16メガバイトが返されます。 batchSize()を使用してその上限を下げられますが、上げることはできません。
find() 操作と aggregate() 操作の初期バッチ サイズは、デフォルトでドキュメント数が 101 です。結果のカーソルに対して発行される後続の getMore 操作には、デフォルトのバッチ サイズがないため、16 MB のメッセージ サイズによってのみ制限されます。
インデックスなしでソート操作を行うクエリでは、サーバーは結果を返す前にすべてのドキュメントをメモリにロードしてソートを実行する必要があります。
ユーザーがカーソルを反復処理して返されたバッチの末尾に到達した際にさらに結果があるとcursor.next() は getMore operation を実行して次のバッチを取得します。カーソルを反復処理する間にバッチに残っているドキュメント数を確認するには、次の例のように objsLeftInBatch() メソッドを使用できます。
var myCursor = db.inventory.find(); var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null; myCursor.objsLeftInBatch();
カーソル情報
db.serverStatus() メソッドは、以下の metrics フィールドを含むドキュメントを返します。metrics フィールドには、次の情報を含む metrics.cursor フィールドが含まれています。
前回のサーバー再起動以降にタイムアウトしたカーソルの数
非アクティブな期間が一定期間続いてもタイムアウトしないよう
DBQuery.Option.noTimeoutオプションで設定されたオープンカーソルの数「ピン留めされた」オープン カーソルの数
オープン カーソルの合計数
db.serverStatus() メソッドを呼び出して、結果から metrics フィールドにアクセスし、その metrics フィールドから cursor フィールドにアクセスする次の例を検討してみましょう。
db.serverStatus().metrics.cursor
次のドキュメントは、その結果です。
{ "timedOut" : <number> "open" : { "noTimeout" : <number>, "pinned" : <number>, "total" : <number> } }