翻译或纠错本页面

mongo 命令行里迭代游标

The db.collection.find() method returns a cursor. To access the documents, you need to iterate the cursor. However, in the mongo shell, if the returned cursor is not assigned to a variable using the var keyword, then the cursor is automatically iterated up to 20 times [1] to print up to the first 20 documents in the results.

The following examples describe ways to manually iterate the cursor to access the documents or to use the iterator index.

手动迭代游标

mongo 命令行里,当你使用 var 关键字把 find() 方法返回的游标赋值给一个变量时,它将不会自动迭代。

在命令行里,你可以调用游标变量迭代最多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);

参见 ref:JavaScript cursor methods <js-query-cursor-methods>driver 文档来获取更多关于游标方法的资料。

[1](1, 2)

你可以使用 DBQuery.shellBatchSize 来改变迭代次数的默认值 20。请参考 ref:mongo-shell-executing-queries 获取更多资料。

迭代器索引

mongo`命令行里,你可以使用 :method:`~cursor.toArray() 方法来迭代游标,并且以数组的形式来返回文档,如下例所示:

var myCursor = db.inventory.find( { type: 2 } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];

The toArray() method loads into RAM all documents returned by the cursor; the toArray() method exhausts the cursor.

另外,一些 驱动 通过在游标上使用索引来提供访问文档的方法(例如 cursor[index] )。对于第一次调用 toArray() 方法这是一个捷径,然后可以在数组结果上使用索引。

请考虑下面的示例:

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 10 minutes of inactivity, or if client has exhausted the cursor. To override this behavior in the mongo shell, you can use the cursor.noCursorTimeout() method:

var myCursor = db.users.find().noCursorTimeout();

After setting the noCursorTimeout option, you must either close the cursor manually with cursor.close() or by exhausting the cursor’s results.

See your driver documentation for information on setting the noCursorTimeout option.

Cursor Isolation

As a cursor returns documents, other operations may interleave with the query. For the MMAPv1 storage engine, intervening write operations on a document may result in a cursor that returns a document more than once if that document has changed. To handle this situation, see the information on snapshot mode.

Cursor Batches

The MongoDB server returns the query results in batches. The amount of data in the batch will not exceed the maximum BSON document size. To override the default size of the batch, see batchSize() and limit().

3.4 新版功能: Operations of type find(), aggregate(), listIndexes, and listCollections return a maximum of 16 megabytes per batch. batchSize() can enforce a smaller limit, but not a larger one.

find() and aggregate() operations have an initial batch size of 101 documents by default. Subsequent getMore operations issued against the resulting cursor have no default batch size, so they are limited only by the 16 megabyte message size.

For queries that include a sort operation without an index, the server must load all the documents in memory to perform the sort before returning any results.

As you iterate through the cursor and reach the end of the returned batch, if there are more results, cursor.next() will perform a getMore operation to retrieve the next batch. To see how many documents remain in the batch as you iterate the cursor, you can use the objsLeftInBatch() method, as in 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 includes a metrics field. The metrics field contains a metrics.cursor field with the following information:

  • 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 a period of inactivity
  • number of “pinned” open cursors
  • total number of open cursors

Consider the following example which calls the db.serverStatus() method and accesses the metrics field from 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>
   }
}