使用nodejs在mongoDB oplog集合中查找每个新文档不起作用(游标似乎变得无效或死亡)

Jos*_*abo 6 mongodb node.js

我想要实现的想法是在创建新文档时读取(查找)mongoDB oplog集合(例如插入到数据库集合中).

这是我的代码简化:

var MongoClient = require('mongodb').MongoClient;

MongoClient.connect(url, function(err, db) {
if(err){console.error("ERROR",err); return;}

console.log("Connected correctly to server");

db.collection('oplog.rs').find({
        ns: 'cabo_dev.documents',
        op: 'i',
        // ts: {
        //  $gte: $gte
        // }
    }, {
        tailable: true
    })
    .each(function (err, entry) {
        if (err) {
            console.error("Error fetching a document", err, entry);
            return;
        }

        console.log('--- entry', entry);
    });
});
Run Code Online (Sandbox Code Playgroud)

我已经评论了$ gte值来简化,但这个想法是读取所有"新"日志,而不是旧日志.我也有类似的代码使用mongoose,而不是原始驱动程序.

根据文档,前面的代码将返回表示插入cabo_dev.documents集合中的所有oplog文档(cabo_dev是db的名称)以及所有新的后续插入.但是,当它完成返回文档('旧'文档)然后没有更多文档要返回时,它会返回下一个输出为错误(错误的每个中的var):

{ [MongoError: No more documents in tailed cursor]
  name: 'MongoError',
  message: 'No more documents in tailed cursor',
  tailable: true,
  awaitData: true }
Run Code Online (Sandbox Code Playgroud)

之后,它不再从oplog中获取更多插入.根据可修改的文档,游标变为死或无效的原因之一是:

  • 查询返回不匹配.

这是我认为在这里发生的事情.但是,在那种情况下,每个进程永远不会结束(当光标变为死或无效时,这是我期望的,不是吗?).但我真的想继续获取后续的插入日志.

我究竟做错了什么?

hav*_*ish 6

可能你现在可能已经找到了答案.但我正在写这个答案,以便任何偶然遇到同样问题的人都可以解决问题.

在我的情况下,mongodb驱动程序版本是2.0.33

与mongodb服务器建立连接后,请执行以下操作:

db.collection('yourCappedColl', function (err, coll) {
                var stream = coll.find({},
                    {
                        tailable: true,
                        awaitdata: true,
                        numberOfRetries: Number.MAX_VALUE
                    }).stream();

                stream.on('data', function(val) {
                    console.log('Doc: %j',val);
                });

                stream.on('error', function(val) {
                    console.log('Error: %j', val);
                });

                stream.on('end', function(){
                    console.log('End of stream');
                });
        });
Run Code Online (Sandbox Code Playgroud)

那是:

  1. 使用stream()而不是每个()
  2. numberOfRetries设置为Number.MAX_VALUE
  3. awaitData设置为true

有关详细信息,请参阅此jira项目:

MongoError:游标中没有更多文档