Kivi

没有什么远大理想,只是永远都不会满足而已


  • 首页

  • 关于

  • 标签

  • 归档

mongos cursor 的使用

发表于 2017-06-01 更新于 2017-07-02 分类于 Node.js 阅读次数:
本文字数: 3k 阅读时长 ≈ 3 分钟

写在前面

mongoose在github上是一个很受欢迎的开源项目,作为加强版的mongo node driver,有很多优点,但是无奈文档不怎么全面,下面是一些关于mongoose cursor的用法总结

环境

  • node 6.9.1
  • mongoose 4.11.0 (如果可能,尽量用新版,开源的东西,你懂的)

cursor基础

参考链接

cursor生命周期

cursor就是mongodb查询游标,利用它可以返回所有的查询结果,可以一次性返回,可以分批返回。

默认情况下,查询游标的生存周期是10分钟,如果在这期间,cursor耗尽(已经返回了所有结果),mongo server也会关闭这个cursor。cursor有选项noTimeout,可以阻止这个默认行为,如果使用了这个选项,就必须要手动关闭cursor或者是药最终有能力耗尽这个cursor。

cursor隔离性

cursor使用过程当中肯定存在一些其他的操作会影响正在查询的数据,如果使用的饰mmapv1存储引擎,在某些情况下,会导致同一个document返回多次的情况,关于这一些,官方文档有详细的说明,建议大家早日更换wt

As a cursor returns documents other operations may interleave with the query: with MMAPv1 storage engine, if some of these operations are updates that cause the document to move (in the case of a table scan, caused by document growth) or that change the indexed field on the index used by the query; then the cursor will return the same document more than once.

Mongodb docdocs.mongodb.com/v3.0/faq/developers/#faq-developers-isolate-cursors

cursor batch

使用游标获取数据的时候,数据是分批返回的。每一批数据不能超过maximum BSON document size,默认情况下,第一批数据返回101条数据或者不超过1MB的数据,之后每次返回4M数据。可以手动设定batch size

mongoose中使用cusror

查询

1
2
3
4
5
6
7
8
9
10
var cursor = UserModel.find({name: 'kivi'}).cursor({batchSize: 100});
cursor.on('data', function (doc) {
// do something
});
cursor.on('end', function (doc) {
console.log('cursor exausted';
});
cursor.on('error', function (err) {
console.log('got error', err);
});

一开始我也想着应该有什么方法能一次性拿到一个batch的数据,最终发现数据还是会一条一条的过来

Batch sizes are just for performance optimisation and will not give you a 50 object chunk.
You will still have to process each doc individually.

stackoverflowstackoverflow.com/questions/42118590/mongoose-cursor-batchsize

聚合

正常情况下,这么用是没问题的

1
2
3
4
5
6
7
8
9
var cursor = model.aggregate(parameters).cursor({ batchSize: 1000 }).exec();
cursor.on('data', function (doc) {
// do something
});
cursor.on('end', function (doc) {
console.log('cursor exausted';
});
cursor.on('error', function (err) {
});

但是上面的写法有的时候cursor是null,这是mongoose的一个bug,连接没有完全建立的时候就会出现这种情况

It’s unfortunately a bug with the first way we implemented aggregation cursors - cursor will be undefined if the model’s underlying connection has not successfully connected. That’s what the async option for agg cursors is for:

model.aggregate(parameters).cursor({ batchSize: 1000, async: true }).exec(function(error, cursor) {
// Can now use cursor
});
The reason why it needs to be async is that mongoose may need to wait for the connection to mongodb to be established before it can actually return the cursor.

mongoosegithub.com/Automattic/mongoose/issues/4694

所以下面的async参数非常有意义

1
2
3
4
5
6
7
8
9
10
11
12
13
UserModel
.aggregate()
.cursor({ batchSize: 100, async: true })
.exec(function (err, cursor) {
cursor.on('data', function (doc) {

});
cursor.on('end', function () {
});
cursor.on('error', function (err) {

});
});

以上是mongoose cursor使用的两个最基本的场景,以后会补充更多关于cursor更加丰富的用法

# Node.js # mongoose
mongodb常用命令整理
mongodb两段提交
  • 文章目录
  • 站点概览
kivi

kivi

nodejs | server
58 日志
17 分类
32 标签
RSS
  1. 1. 写在前面
  2. 2. 环境
  3. 3. cursor基础
    1. 3.1. cursor生命周期
    2. 3.2. cursor隔离性
    3. 3.3. cursor batch
  4. 4. mongoose中使用cusror
    1. 4.1. 查询
    2. 4.2. 聚合
© 2019 kivi | 173k | 2:37
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0
|