首页 > mongodb > basic > 16.MongoDb遍历结果cursor

16.MongoDb遍历结果cursor

db.collection.find()方法返回一个结果指针. 访问结果数据需要对指针进行迭代查询. 在mongo命令中, 查询结果cursor默认返回20条数据, 默认对cursor进行迭代20次. 可以通过修改DBQuery.shellBatchSize值来改变结果显示数量.

1 mongodb手动遍历查询结果cursor

可以通过以下语句, 打印前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());
}

可以使用cursor提供的forEach()方法来遍历结果集.

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

myCursor.forEach(printjson);

cursor相关的其他方法: JavaScript cursor methods

2 mongodb遍历索引

在mongo命令中可以通过toArray()方法遍历结果集, 并将结果集放在一个数组中返回.

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

toArray()方法将全部结果数据放在内存中.toArray()遍历完全部指针数据.

有部分Mongodb数据库驱动提供根据cursor索引位置获取文档数据的方法.(例如:cursor[index]). 这是先调用toArray()方法再用索引获取数组中元素的简写.

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

myCursor[1]等同于以下:

myCursor.toArray() [1];

3 mongodb Cursor行为

3.1 关闭不活动的Cursor

默认情况下, 一个Cursor停止使用超过10分钟或者客户端使用完毕, 服务器会自动关闭这个Cursor. 在mongo命令中, 可以通过cursor.noCursorTimeout()方法, 改变这个行为.

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

设定noCursorTimeout这个选项后,你必须通过cursor.close()方法手动关闭, 或者用尽cursor的结果集.

3.2 Cursor分离

一个Cursor返回的数据文档, 其他的操作可能交错执行. MMMPv1存储引擎中, 交错执行写操作, 可能导致返回的cursor中包含多次同样的一条数据. 处理这种情况, 参考snapshot mode.

3.3 Cursor批处理

MongoDB服务器将结果打包返回. 数据包的大小不能超过默认BOSN文档大小(16M)maximum BSON document size. 可以通过batchSize()limit()来修改返回结果集.

3.4 版本新特性 find(), aggregate(), listIndexes, 和listCollections每批返回最大16M的数据.batchSize()可以设置一个更小的限制, 而不是最大的限制.find()aggregate()默认初始集合文档数量是101.3.2版本以后的getMore`操作,没有默认集合文档数量限制, 只是有16M最大字节数限制.

注:查询没有索引的数据, 通过sort排序时, 返回结果前, 服务器必须将全部数据加载进内存中来实现排序.

遍历结果集到达返回数据的末尾时, 如果有更多的数据, cursor.next()方法会执行getMore operation操作来得到下一批数据. 可以通过objsLeftInBatch()方法来查看在当前数据还有多少数据没有遍历.

var myCursor = db.inventory.find();

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

myCursor.objsLeftInBatch();

4 Cursor信息

db.serverStatus()方法返回一个文档,其中包括了metrics字段.metrics字段中有个额metrics.cursor字段中的信息:

  • 最后一次服务器重启以来超时cursor数量
  • 由于设置DBQuery.Option.noTimeout来防止超时,打开的cursor数量.
  • pinned open cursor 数量.
  • 打开的cursor全部数量.

使用示例:

db.serverStatus().metrics.cursor

显示结果:

{
   "timedOut" : <number>
   "open" : {
      "noTimeout" : <number>,
      "pinned" : <number>,
      "total" : <number>
   }
}

5 参考文章

https://docs.mongodb.com/manual/tutorial/iterate-a-cursor/

6 相关文章

MongoDB中文文档

转载请保留原文链接.