进入MongoDB中文手册(4.2版本)目录
db.collection.find()方法返回一个游标。要访问文档,您需要迭代游标。但是,在 mongo shell中,如果未使用var关键字将返回的光标分配给变量,则光标将自动迭代多达20次,以便打印出结果中的前20个文档。
以下示例描述了手动迭代游标以访问文档或使用迭代器索引的方法。
1 手动迭代游标
在mongo shell中,当您使用var关键字将find()方法返回的游标分配给变量时,游标不会自动进行迭代。
您可以在shell中调用cursor变量,进行多达20次迭代并打印匹配的文档,如以下示例所示:
var myCursor = db.users.find( { type: 2 } );
myCursor
您还可以使用cursor方法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游标方法和驱动程序文档。
提示
可以使用DBQuery.shellBatchSize将迭代次数的默认值20改变成新的值。有关更多信息,请参阅 使用mongo Shell。
2 迭代索引(Index)
在mongo shell中,可以使用 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];
3 游标行为
3.1 关闭非活动游标
默认情况下,服务器将在闲置10分钟或客户端用尽光标后自动关闭光标。要在mongo shell中覆盖此行为,可以使用以下cursor.noCursorTimeout()方法:
var myCursor = db.users.find().noCursorTimeout();
设置noCursorTimeout选项后,必须使用cursor.close()或通过用尽光标的结果来关闭光标。
有关设置noCursorTimeout选项的信息,请参见驱动程序文档。
3.2 游标隔离
当游标返回文档时,其他操作可能会与查询交错。
3.3 游标批次
MongoDB服务器批量返回查询结果。批处理中的数据量将不超过BSON文档的最大大小。要覆盖批次的默认大小,请参见batchSize()和 limit()。
新版本3.4中:类型的操作find(), aggregate(), listIndexes,和 listCollections每批返回数据量最大16兆字节。batchSize()可以强制执行一个较小的限制,但不能执行较大的限制。
find()和aggregate()操作的初始批处理大小默认为101个文档。针对生成的游标发出的后续getMore操作没有默认的批处理大小,因此它们仅受16 MB消息大小的限制。
对于包含不带索引的排序操作的查询,服务器必须在返回任何结果之前将所有文档加载到内存中以执行排序。
当您遍历游标并到达返回批次的末尾时,如果有更多结果,cursor.next()将执行getMore操作来检索下一个批次。要查看在迭代游标时批处理中剩余多少文档,可以使用objsLeftInBatch()方法,如以下示例所示:
var myCursor = db.inventory.find();
var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;
myCursor.objsLeftInBatch();
4 游标信息
db.serverStatus()方法返回包含metrics字段的文档。metrics字段包含具有以下信息的metrics.cursor字段:
- 自上次服务器重新启动以来超时的游标数;
- 选项为DBQuery.Option.noTimeout的打开游标的数量,设置该选项可以防止一段时间不活动后超时;
- “固定(pinned)”打开游标的数量;
- 打开的游标总数。
考虑以下示例,该示例调用 db.serverStatus()方法并从结果中访问metrics字段,然后从metrics字段中访问cursor字段:
db.serverStatus().metrics.cursor
结果是以下文档:
{
"timedOut" : <number>
"open" : {
"noTimeout" : <number>,
"pinned" : <number>,
"total" : <number>
}
}
也可以看看
db.serverStatus()