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:

  1. var myCursor = db.users.find( { type: 2 } );
  2.  
  3. myCursor

You can also use the cursor method next() toaccess the documents, as in the following example:

  1. var myCursor = db.users.find( { type: 2 } );
  2.  
  3. while (myCursor.hasNext()) {
  4. print(tojson(myCursor.next()));
  5. }

As an alternative print operation, consider the printjson() helpermethod to replace print(tojson()):

  1. var myCursor = db.users.find( { type: 2 } );
  2.  
  3. while (myCursor.hasNext()) {
  4. printjson(myCursor.next());
  5. }

You can use the cursor method forEach() toiterate the cursor and access the documents, as in the followingexample:

  1. var myCursor = db.users.find( { type: 2 } );
  2.  
  3. 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:

  1. var myCursor = db.inventory.find( { type: 2 } );
  2. var documentArray = myCursor.toArray();
  3. 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:

  1. var myCursor = db.users.find( { type: 2 } );
  2. var myDocument = myCursor[1];

The myCursor[1] is equivalent to the following example:

  1. 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:

  1. 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 getMoreoperations 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:

  1. var myCursor = db.inventory.find();
  2.  
  3. var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;
  4.  
  5. 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 optionDBQuery.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 metricsfield:

  1. db.serverStatus().metrics.cursor

The result is the following document:

  1. {
  2. "timedOut" : <number>
  3. "open" : {
  4. "noTimeout" : <number>,
  5. "pinned" : <number>,
  6. "total" : <number>
  7. }
  8. }

See also

db.serverStatus()