【问题标题】:NodeJS writes to MongoDB only onceNodeJS 只向 MongoDB 写入一次
【发布时间】:2017-02-20 01:04:25
【问题描述】:

我有一个 NodeJS 应用程序,它应该以同步方式(多个嵌套的 for 循环)生成大量数据集。这些数据集应该保存到我的 MongoDB 数据库中,以便以后更有效地查找它们。

我使用 mongodb - NodeJS 驱动程序并运行一个守护进程。与数据库的连接工作正常,根据守护程序窗口,第一组数据集已成功存储。每隔约 400-600 毫秒,就会存储另一个组,但是在第一个数据集之后,MongoDB 控制台中不再有输出(甚至没有错误),并且由于文件大小没有增加,我假设这些写入操作不起作用(我不能等待它完成,因为它需要好几天才能完全运行)。

如果我重新启动 NodeJS 脚本,它甚至不会再保存第一个键,可能是因为重复?如果我删除 db 文件夹内容,第一个将再次保存。

这是我脚本的重要部分,我找不到任何我做错的地方。我认为问题更多在于内部逻辑(奇怪的重复检查/不运行并发等)。

var MongoClient = require('mongodb').MongoClient, dbBuffer = [];
MongoClient.connect('mongodb://127.0.0.1/loremipsum', function(err, db) {
    if(err) return console.log("Cant connect to MongoDB");
    var collection = db.collection('ipsum');
    console.log("Connected to DB");

    for(var q=startI;q<endI;q++) {
        for(var w=0;w<words.length;w++) {
            dbBuffer.push({a:a, b:b});
        }
        if(dbBuffer.length) {
            console.log("saving "+dbBuffer.length+" items");
            collection.insert(dbBuffer, {w:1}, function(err, result) {
                if(err) {
                    console.log("Error on db write", err);
                    db.close();
                    process.exit();
                }
            });
        }
        dbBuffer = [];
    }
    db.close();
});

更新

  • db.close 永远不会被调用并且连接不会断开
  • 更改为批量插入不会改变任何内容
  • 永远不会调用插入的回调 - 这可能是问题所在! MongoDB 控制台确实告诉我插入过程成功,但驱动程序和 MongoDB 之间的通信似乎无法正常进行插入。

【问题讨论】:

  • collection.insert 是一个异步调用,因此您的最终db.close() 调用发生在这些调用完成之前。
  • 另外,这是 Bulk.insert 的一个很好的用例(而不是 dbBuffer 数组破解)
  • @JohnnyHK 如前所述,这是一个实际运行多天的多个嵌套循环的简化示例。我可以在 MongoDB 控制台中看到连接也没有关闭。 Felipe:你说得对,我会试一试,但应该不会有太大区别。
  • 现在更改代码并在另一台机器上运行,同样的问题。

标签: node.js mongodb


【解决方案1】:

我自己“解决”了它。我的一个误解是,每个插入事务都在 MongoDB 控制台中得到确认,而实际上它只确认第一个事务,或者命令之间是否有一段时间。要检查插入过程是否真的有效,需要运行脚本一段时间并等待 MongoDB 将其转储到本地文件中(大约 30-60 秒)。

此外,插入过程彼此之间的速度太快,MongoDB 似乎无法在 Win10 x64 下正确处理此问题。我从 Array-Buffer 更改为内部缓冲区(参见 cmets),并且仅在插入之前的数据后继续该过程。

这是简化的结果代码

db.collection('seedlist', function(err, collection) {
    syncLoop(0,0, collection);
    //...
});

function syncLoop(q, w, collection) {
    batch = collection.initializeUnorderedBulkOp({useLegacyOps: true});
    for(var e=0;e<words.length;e++) {
        batch.insert({a:a, b:b});
    }
    batch.execute(function(err, result) {
        if(err) throw err;
        //...
        return setTimeout(function() {
            syncLoop(qNew,wNew,collection);
        }, 0); // Timer to prevent Memory leak
    });
}

【讨论】:

    猜你喜欢
    • 2017-09-27
    • 1970-01-01
    • 2017-03-20
    • 1970-01-01
    • 2014-08-15
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多