插入许多文档后关闭node.js中的mongodb连接

这个问题已经被问到,但OP接受的答案没有满足我的特殊需求.

closing mongodb connection in node.js while inserting lot of data

我有一个实用程序脚本,可以为多个集合添加大量记录.实际上它只是一个导入,使用byline读取非常大的文本文件,然后将数据插入到集合中:

var MongoClient = require("mongodb").MongoClient;
var fs = require("fs");
var byline = require("byline");

var inStream = fs.createReadStream("data.txt",{ encoding: "utf8" });

var byLinestream = byline.createStream(inStream);

MongoClient.connect("mongodb://localhost:27017/test",{ native_parser: true},function(err,db) {  
    var collection = db.collection("Data");
    db.dropCollection("Data",result) {
        byLinestream.on("data",function(line) {
            var o = parseLinetoObject(line);
            collection.insert(o);
        });
    });
});

建议的答案是将所有数据推送到一个数组中,然后在完成后使用单个write和一个回调来关闭数据库.这不是一个好的答案,因为我正在使用的文件非常大,因此消耗大量内存.

提交给类似question的另一个解决方案是使用异步包来创建一个函数数组,然后并行运行它们.另一个半身像,但至少它不会创造一个巨大的单一插入.

所以问题是:如果所有插入完成后如何关闭MongoDB连接,以便我的脚本退出并且不挂起?

我应该补充一点,我已经尝试了计数方法,我在insert回调中增加一个计数器变量.它不起作用,因为在插入中的某个时刻,回调执行和完成的速度比插入完成的速度快,导致计数器在插入仍然继续时命中0,从而关闭数据库.

解决方法

您应该在读取所有行时设置标志:

var readAllLines = false;

byLinestream.on("end",function() {
  readAllLines = true;
});

接下来,在插入每条记录后检查该标志.但是,您还需要跟踪已读取的行数以及插入的行数,因此如果已插入所有行(甚至不按顺序),则只关闭数据库.

把所有东西放在一起:

db.dropCollection("Data",result) {
  var lineCount     = 0;
  var readAllLines  = false;

  byLinestream.on("end",function() {
    readAllLines = true;
  });

  byLinestream.on("data",function(line) {
    lineCount++;
    var o = parseLinetoObject(line);
    collection.insert(o,{ w : 1 },function() {
      if (--lineCount === 0 && readAllLines) {
        // we've read and inserted all lines
        db.close();
      }
    });
  });
});

但是,我确实认为将回调传递给insert(‘安全模式’)比当前的解决方案要慢,在那里你调用insert但不等待其结果.为了加快速度,您可以在将它们插入一个语句之前缓冲X行数量,而不是单独写入每一行.

与此类似的东西(没有行计数):

var buffer = [];
byLinestream.on("data",function(line) {
  buffer.push(parseLinetoObject(line));
  if (buffer.length > 100 || readAllLines) {
    collection.insert(buffer,function() {
      if (readAllLines) {
        db.close();
      }
    });
    buffer = [];
  }
});

相关文章

这篇文章主要介绍“基于nodejs的ssh2怎么实现自动化部署”的...
本文小编为大家详细介绍“nodejs怎么实现目录不存在自动创建...
这篇“如何把nodejs数据传到前端”文章的知识点大部分人都不...
本文小编为大家详细介绍“nodejs如何实现定时删除文件”,内...
这篇文章主要讲解了“nodejs安装模块卡住不动怎么解决”,文...
今天小编给大家分享一下如何检测nodejs有没有安装成功的相关...