Mongo的Cursor.nextObject有时会错误地返回Null?

时间:2014-08-06 08:02:58

标签: node.js mongodb

我正在组合async.queueCursor.nextObject来迭代游标并针对返回的文档执行一些异步工作。

已经有一个很棒的小程序包,https://www.npmjs.org/package/mongo-cursor-processing,但遗憾的是它并没有公开我需要的底层队列。

所以,我尝试自己实现它,但遇到了障碍。有时,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));
}

控制台日志显示:

... 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 ...

有时,<none> <none>行会在下一次调用成功之前重复两次。

真正有趣的部分是当我在Mongo shell中执行查询时,在511abbd59c0d972a3e000122511abbd59c0d972a3e000125打印到控制台之间会有暂停。暂停持续大约0.75秒,并且正好在光标中命中空文档的位置。我在查询中迭代了数千个文档,这是我遇到的唯一停顿。此外,检查空值两侧的两个文件没有显示出特殊性。

任何可能导致两种可能相关现象的想法?

1 个答案:

答案 0 :(得分:1)

我仍然不确定是什么导致暂停,但似乎这是罪魁祸首。

在暂停期间,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));
}