Iterate a Cursor in the mongo Shell
The db.collection.find()
method returns a cursor. To accessthe documents, you need to iterate the cursor. However, in themongo
shell, if the returned cursor is not assigned to avariable using the var
keyword, then the cursor is automaticallyiterated up to 20 times [1] to print up to thefirst 20 documents in the results.
The following examples describe ways to manually iterate the cursor toaccess the documents or to use the iterator index.
Manually Iterate the Cursor
In the mongo
shell, when you assign the cursor returned fromthe find()
method to a variable usingthe var
keyword, the cursor does not automatically iterate.
You can call the cursor variable in the shell to iterate up to 20 times[1] and print the matching documents, as in thefollowing example:
- var myCursor = db.users.find( { type: 2 } );
- myCursor
You can also use the cursor method next()
toaccess the documents, as in the following example:
- var myCursor = db.users.find( { type: 2 } );
- while (myCursor.hasNext()) {
- print(tojson(myCursor.next()));
- }
As an alternative print operation, consider the printjson()
helpermethod to replace print(tojson())
:
- var myCursor = db.users.find( { type: 2 } );
- while (myCursor.hasNext()) {
- printjson(myCursor.next());
- }
You can use the cursor method forEach()
toiterate the cursor and access the documents, as in the followingexample:
- var myCursor = db.users.find( { type: 2 } );
- myCursor.forEach(printjson);
See JavaScript cursor methods and yourdriver documentation for moreinformation on cursor methods.
[1] | (1, 2) You can use the DBQuery.shellBatchSize tochange the number of iteration from the default value 20 . SeeWorking with the mongo Shell for more information. |
Iterator Index
In the mongo
shell, you can use thetoArray()
method to iterate the cursor and returnthe documents in an array, as in the following:
- var myCursor = db.inventory.find( { type: 2 } );
- var documentArray = myCursor.toArray();
- var myDocument = documentArray[3];
The toArray()
method loads into RAM alldocuments returned by the cursor; the toArray()
method exhausts the cursor.
Additionally, some drivers provideaccess to the documents by using an index on the cursor (i.e.cursor[index]
). This is a shortcut for first calling thetoArray()
method and then using an indexon the resulting array.
Consider the following example:
- var myCursor = db.users.find( { type: 2 } );
- var myDocument = myCursor[1];
The myCursor[1]
is equivalent to the following example:
- myCursor.toArray() [1];
Cursor Behaviors
Closure of Inactive Cursors
By default, the server will automatically close the cursor after 10minutes of inactivity, or if client has exhausted the cursor. Tooverride this behavior in the mongo
shell, you can usethe cursor.noCursorTimeout()
method:
- var myCursor = db.users.find().noCursorTimeout();
After setting the noCursorTimeout
option, you must either close the cursormanually with cursor.close()
or by exhausting the cursor’s results.
See your driver documentation forinformation on setting the noCursorTimeout
option.
Cursor Isolation
As a cursor returns documents, other operations may interleave with thequery.
Cursor Batches
The MongoDB server returns the query results in batches. The amount ofdata in the batch will not exceed the maximum BSON document size. To override the default size ofthe batch, see batchSize()
andlimit()
.
New in version 3.4: Operations of type find()
,aggregate()
,listIndexes
, andlistCollections
return a maximum of 16 megabytesper batch. batchSize()
can enforce a smallerlimit, but not a larger one.
find()
and aggregate()
operations have an initial batch sizeof 101 documents by default. Subsequent getMore
operations issued against the resulting cursor have no default batchsize, so they are limited only by the 16 megabyte message size.
For queries that include a sort operation without an index, theserver must load all the documents in memory to perform the sortbefore returning any results.
As you iterate through the cursor and reach the end of the returnedbatch, if there are more results, cursor.next()
will performa getMore operation
to retrieve the next batch.To see how many documents remain in the batch as you iterate thecursor, you can use the objsLeftInBatch()
method, asin the following example:
- var myCursor = db.inventory.find();
- var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;
- myCursor.objsLeftInBatch();
Cursor Information
The db.serverStatus()
method returns a document that includesa metrics
field. Themetrics
field contains ametrics.cursor
field with the followinginformation:
- number of timed out cursors since the last server restart
- number of open cursors with the option
DBQuery.Option.noTimeout
set to prevent timeout after aperiod of inactivity - number of “pinned” open cursors
- total number of open cursors
Consider the following example which calls thedb.serverStatus()
method and accesses the metrics
fieldfrom the results and then the cursor
field from the metrics
field:
- db.serverStatus().metrics.cursor
The result is the following document:
- {
- "timedOut" : <number>
- "open" : {
- "noTimeout" : <number>,
- "pinned" : <number>,
- "total" : <number>
- }
- }
See also