Node.js Mongo';s Cursor.nextObject有时会错误地返回Null?
我将结合Node.js Mongo';s Cursor.nextObject有时会错误地返回Null?,node.js,mongodb,Node.js,Mongodb,我将结合async.queue和Cursor.nextObject来迭代游标,并对返回的文档执行一些异步工作 有一个很好的小程序包已经做到了这一点,但不幸的是,它没有公开我需要的底层队列 因此,我尝试自己实现它,但遇到了一个障碍。有时,Cursor.nextObject返回null,而实际上有更多文档 下面是我附加到队列的一个小代码片段,以说明: if (this.cursor && this.length() < this.concurrency) { this.
async.queue
和Cursor.nextObject
来迭代游标,并对返回的文档执行一些异步工作
有一个很好的小程序包已经做到了这一点,但不幸的是,它没有公开我需要的底层队列
因此,我尝试自己实现它,但遇到了一个障碍。有时,Cursor.nextObject
返回null
,而实际上有更多文档
下面是我附加到队列的一个小代码片段,以说明:
if (this.cursor && this.length() < this.concurrency) {
this.cursor.nextObject(function(err, item) {
console.log(this.name + ': ' + (item ? item._id : '<null>') + ' ' + (err ? err : '<null>'));
if (item) {
this.push(item);
} else {
// delete this.cursor;
}
}.bind(this));
}
if(this.cursor&&this.length()
控制台日志显示:
... Maybe 100 lines ...
prop-queue: 511abbd59c0d972a3e000119 <none>
prop-queue: 511abbd59c0d972a3e00011d <none>
prop-queue: 511abbd59c0d972a3e000120 <none>
prop-queue: 511abbd59c0d972a3e000122 <none>
prop-queue: <none> <none>
prop-queue: 511abbd59c0d972a3e000125 <none>
prop-queue: 511abbd59c0d972a3e000127 <none>
prop-queue: 511abbd59c0d972a3e000129 <none>
prop-queue: 511abbd59c0d972a3e00012c <none>
... 1000's more lines before the next null ...
。。。也许100行。。。
道具队列:511abbd59c0d972a3e000119
道具队列:511abbd59c0d972a3e00011d
道具队列:511abbd59c0d972a3e000120
道具队列:511abbd59c0d972a3e000122
道具队列:
道具队列:511abbd59c0d972a3e000125
道具队列:511abbd59c0d972a3e000127
道具队列:511abbd59c0d972a3e000129
道具队列:511abbd59c0d972a3e00012c
... 在下一个空值之前还有1000行。。。
有时,在下一次调用成功之前,
行会重复两次
真正有趣的是,当我在Mongo shell中执行查询时,在控制台上打印511abbd59c0d972a3e000122
和511abbd59c0d972a3e000125
时,中间会有一个停顿。暂停时间约为0.75秒,就在光标击中空文档的位置。我在查询中迭代了数千个文档,这是我唯一经历的暂停。此外,检查null两侧的两个文档没有任何特殊性
你知道是什么导致了这两种可能相关的现象吗?我仍然不确定是什么导致了停顿,但似乎是罪魁祸首 在暂停期间,
Cursor.nextObject
在第一个返回之前被调用多次。其中一些调用返回null
。解决方案是确保从不并发调用Cursor.nextObject
if (this.cursor && !this.cursor_exec && this.length() < this.concurrency) {
this.cursor_exec = true;
this.cursor.nextObject(function(err, item) {
console.log(this.name + ': ' + (item ? item._id : null) + ' ' + (err ? err : null));
this.cursor_exec = false;
if (item) {
this.push(item);
} else {
delete this.cursor;
}
}.bind(this));
}
if(this.cursor&&!this.cursor\u exec&&this.length()
使用[event stream interface]比调用.nextObject()
更好。您可以在节点流的“数据”事件中将项目添加到“队列”。MongoDB的节点驱动程序支持将游标作为流返回,而实际上像aggregate()
这样的方法只返回基本上已经是可读流的内容。@NeilLunn你在说什么?如果是这样,如果我忙于处理已经收到的文档,我将如何“减慢”流?整个队列思想背后的推动力是,我以前使用过each()
,但我的进程一直在内存不足并被杀死。