赞
踩
db.collection.find()
方法会返回一个游标,要访问文档,需要遍历游标。不过,在mongosh中,如果没有使用var关键字将返回的游标赋值给变量,游标默认会自动迭代20次,打印结果中的前20个文档。本文会介绍在mongosh中迭代游标的一些方法,包括手动迭代游标以访问文档或使用迭代器索引的方法。
在mongosh中,可以使用var
关键字将find()
方法返回的游标赋值给一个变量,这样游标就不会自动遍历了。此时,可以在shell中调用游标变量,默认遍历20次,并打印出匹配的文档,如下例所示:
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);
还可以设置DBQuery.shellBatchSize
属性来更改默认值20的遍历文档数。
在mongosh中,可以使用toArray()
方法遍历游标,并以数组形式返回文档,如下所示:
var myCursor = db.inventory.find( { type: 2 } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];
toArray()
方法会将游标返回的所有文档加载到内存中,注意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()
手动关闭游标,或者通过耗尽游标来闭游标。
当游标返回文档时,其他操作可能会与查询交错进行。
MongoDB 服务器会分批返回查询结果,批次中的数据量不会超过BSON文档的最大大小,可以使用batchSize()
和limit()
覆盖默认的批处理大小。find()
、aggregate()
、listIndexes
和listCollections
类型的操作每批最多返回16兆字节。
find()
和aggregate()
操作的默认批次大小为101个文档。针对结果游标发出的后续getMore
操作没有默认批量大小,因此它们只受 16 兆字节大小的限制。
对于包含不带索引的排序操作的查询,服务器必须在返回任何结果之前加载内存中的所有文档以执行排序。
当遍历游标并到达返回批次的末尾时,如果还有更多结果,cursor.next()
将执行getMore
操作以获取下一批结果。要在遍历游标时查看批次中还剩余多少文档,可以使用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>
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。