跳到主要内容

游标

2025年02月25日
柏拉文
越努力,越幸运

一、认识


二、获取


2.1 db.collection.find()

db.collection.find() 方法返回一个游标。要访问文档,需要迭代游标。但是,在 mongosh 中,如果未使用 var 关键字将返回的游标分配给变量,则该游标会自动迭代多达 20[1],最多可在结果中输出前 20 个文档。

游标遍历:

  • 基于 next() 遍历游标: 可以使用游标方法 next() 访问文档

    var myCursor = db.users.find( { type: 2 } );
    while (myCursor.hasNext()) {
    print(tojson(myCursor.next()));
    }
  • 基于 forEach() 遍历游标: 使用游标方法 forEach() 来迭代游标并访问文档

    var myCursor =  db.users.find( { type: 2 } );
    myCursor.forEach(printjson);
  • 基于 toArray() 遍历游标: 使用 toArray() 方法遍历游标,并以数组形式返回文档。toArray() 方法会将游标返回的所有文档加载到 RAM 中;toArray() 方法会耗尽游标。

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

游标行为: 从 MongoDB 5.0 开始,在客户端会话中创建的游标将在以下情况下关闭:相应的服务器会话以 killSessions 命令结束、会话超时或客户端已用尽游标时。

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

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

    设置 noCursorTimeout 选项后,必须使用 cursor.close() 手动关闭游标,或者用尽游标的结果。

  • 使用游标时的并发更新: 当游标返回文档时,其他操作可能会在背景运行并影响结果,具体取决于读关注(read concern)级别。

2.2 db.collection.aggregate()

db.collection.aggregate() 提供对聚合管道的访问权限, 并计算集合或视图中数据的聚合值。返回在聚合分析管道的最后阶段生成的文档游标。如果管道包含 explain 选项,查询将返回一个详细说明聚合操作处理的文档。如果管道包含 $out$merge 操作符,查询将返回一个空游标。