当前位置:   article > 正文

MongoDB CRUD操作:mongosh 游标迭代

MongoDB CRUD操作:mongosh 游标迭代

MongoDB CRUD操作:mongosh 游标迭代


在mongosh中,执行 db.collection.find()方法会返回一个游标,要访问文档,需要遍历游标。不过,在mongosh中,如果没有使用var关键字将返回的游标赋值给变量,游标默认会自动迭代20次,打印结果中的前20个文档。本文会介绍在mongosh中迭代游标的一些方法,包括手动迭代游标以访问文档或使用迭代器索引的方法。

手动迭代光标

在mongosh中,可以使用var关键字find()方法返回的游标赋值给一个变量,这样游标就不会自动遍历了。此时,可以在shell中调用游标变量,默认遍历20次,并打印出匹配的文档,如下例所示:

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

myCursor
  • 1
  • 2
  • 3

也可以使用游标的方法next()访问文档,如下例所示:

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

while (myCursor.hasNext()) {
   print(tojson(myCursor.next()));
}
  • 1
  • 2
  • 3
  • 4
  • 5

作为打印操作的替代方法,可以使用printjson()方法来替代print(tojson()),如:

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

while (myCursor.hasNext()) {
   printjson(myCursor.next());
}
  • 1
  • 2
  • 3
  • 4
  • 5

也可以使用游标的forEach()方法遍历游标并访问文档,如下例所示:

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

myCursor.forEach(printjson);
  • 1
  • 2
  • 3

还可以设置DBQuery.shellBatchSize属性来更改默认值20的遍历文档数。

使用数组迭代

在mongosh中,可以使用toArray()方法遍历游标,并以数组形式返回文档,如下所示:

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

toArray()方法会将游标返回的所有文档加载到内存中,注意toArray()方法可能会耗尽游标。

此外,有些驱动程序通过使用游标上的索引(即cursor[index])来访问文档,就是首先调用toArray()方法,然后在生成的数组上使用索引的方式。

如下面的例子:

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

myCursor[1] 等价于下面的示例:

myCursor.toArray() [1];
  • 1

游标行为

在会话中打开的游标

从MongoDB 5.0开始,客户端会话中创建的游标会在使用killSessions命令后、会话超时或客户端耗尽游标时关闭。默认情况下,服务器会话的超时时间为30分钟,可以通过在启动mongod时设置localLogicalSessionTimeoutMinutes参数进行修改。

在会话之外打开游标

会话下未打开的游标会在10分钟不活动后或客户端耗尽游标后自动关闭。要在mongosh中阻止此行为,可以使用cursor.noCursorTimeout()方法:

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

设置noCursorTimeout选项后,必须使用cursor.close()手动关闭游标,或者通过耗尽游标来闭游标。

游标隔离

当游标返回文档时,其他操作可能会与查询交错进行。

游标批次

MongoDB 服务器会分批返回查询结果,批次中的数据量不会超过BSON文档的最大大小,可以使用batchSize()limit()覆盖默认的批处理大小。find()aggregate()listIndexeslistCollections类型的操作每批最多返回16兆字节。

find()aggregate()操作的默认批次大小为101个文档。针对结果游标发出的后续getMore操作没有默认批量大小,因此它们只受 16 兆字节大小的限制。

对于包含不带索引的排序操作的查询,服务器必须在返回任何结果之前加载内存中的所有文档以执行排序。

当遍历游标并到达返回批次的末尾时,如果还有更多结果,cursor.next()将执行getMore操作以获取下一批结果。要在遍历游标时查看批次中还剩余多少文档,可以使用objsLeftInBatch()方法,如下所示:

var myCursor = db.inventory.find();

var myFirstDocument = myCursor.hasNext() ? myCursor.next() : null;

myCursor.objsLeftInBatch();
  • 1
  • 2
  • 3
  • 4
  • 5

光标信息

db.serverStatus()方法会返回一个包含metrics``字段的文档。metrics字段包含一个metrics.cursor字段,其中包含以下信息:

  • 上次服务器重启后超时的游标数
  • DBQuery.Option.noTimeout选项以防止在一段时间不活动后超时的打开游标数
  • 被持有的打开游标数
  • 打开游标总数

下面的示例调用了db.serverStatus()方法,并访问了结果中的metrics字段,然后又访问了metrics字段中的cursor字段:

db.serverStatus().metrics.cursor
  • 1

结果为类似下面的文档:

{
   "timedOut" : <number>
   "open" : {
      "noTimeout" : <number>,
      "pinned" : <number>,
      "total" : <number>
   }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/648225
推荐阅读
相关标签
  

闽ICP备14008679号