在mongosh中迭代游标mongosh
的db.collection.find()
方法返回一个游标。要访问文档,您需要迭代游标。然而,在mongosh
中,如果使用var
关键字没有将返回的游标赋给变量,那么游标将自动迭代20次,以打印结果中的前20个文档。
以下示例描述了手动迭代游标以访问文档或使用迭代器索引的方法。
手动迭代游标
在 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);
请参阅 JavaScript 游标方法 和您的 驱动程序 文档,了解有关游标方法的更多信息。
[1] | (1, 2) 您可以设置 DBQuery.shellBatchSize 属性来更改文档数量,从默认值 20 。 |
迭代器索引
在 mongosh
中,你可以使用 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];
游标行为
会话中打开的游标
从 MongoDB 5.0 开始,在客户端会话中创建的光标,当相应的服务器会话通过 客户端会话 结束时,或者会话超时,或者客户端耗尽光标时,将关闭。使用 服务器会话 的 killSessions
命令可以结束会话。
默认情况下,服务器会话的超时时间为 30 分钟。要更改此值,请在启动 mongod
时设置 localLogicalSessionTimeoutMinutes
参数。
会话外的光标
未在会话下打开的光标在 10 分钟不活动后或客户端耗尽光标后将自动关闭。要在 mongosh
中覆盖此行为,可以使用 cursor.noCursorTimeout()
方法。
var myCursor = db.users.find().noCursorTimeout();
设置 noCursorTimeout
选项后,您必须手动使用 cursor.close()
或耗尽光标的结果来关闭光标。
有关设置 noCursorTimeout
选项的信息,请参阅您的 驱动程序 文档。
光标隔离
当光标返回文档时,其他操作可能会与查询交织。
光标批处理
MongoDB服务器以批量的方式返回查询结果。批次中的数据量不会超过最大BSON文档大小。要覆盖批次的默认大小,请参阅batchSize()
和limit()
。
类型为find()
、aggregate()
、listIndexes
和listCollections
的操作每批次返回的最大数据量为16兆字节。batchSize()
可以强制实施较小的限制,但不能是较大的限制。
find()
和aggregate()
操作默认的初始批次大小为101个文档。针对结果光标发出的后续getMore
操作没有默认的批次大小,因此它们仅受16兆字节的消息大小的限制。
对于包含排序操作但没有索引的查询,服务器必须在返回任何结果之前将所有文档加载到内存中以执行排序。
在迭代光标并到达返回的批次末尾时,如果还有更多结果,cursor.next()
将执行一个getMore操作
以检索下一批次。要查看在迭代光标时批次中剩余的文档数量,可以使用objsLeftInBatch()
方法,如下例所示
var myCursor = db.inventory.find(); var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null; myCursor.objsLeftInBatch();
不存在的 mongos
数据库的游标结果
从 MongoDB 7.2 版本开始,尝试使用 mongos 部署上不存在的数据库的聚合管道查询将返回验证错误。
在之前的版本中,这些聚合查询返回空游标。
游标信息
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> } }