使用nodejs将非常大的记录集导入MongoDB

时间:2011-11-08 04:09:03

标签: mongodb node.js mongoose

在我深入研究我的问题之前,我想指出我正在做这部分以熟悉node和mongo。我意识到可能有更好的方法来实现我的最终目标,但我想要摆脱的是一种可能适用于其他情况的一般方法。

目标:

我有一个包含600多万个地理IP记录的csv文件。每条记录总共包含4个字段,文件大约为180mb。

我想处理这个文件并将每条记录插入名为“Blocks”的MongoDB集合中。每个“块”将包含csv文件中的4个字段。

我目前的做法

我正在使用mongoose创建一个“Block”模型和一个ReadStream来逐行处理文件。我正在使用的代码来处理文件并提取记录,如果我愿意,我可以将它打印到控制台。

对于文件中的每条记录,它调用一个创建新Blocks对象的函数(使用mongoose),填充字段并保存。

这是每次读取和解析一行时调用的函数内部的代码。 “rec”变量包含一个表示文件中单个记录的对象。

block = new Block();

block.ipFrom    = rec.startipnum;
block.ipTo      = rec.endipnum;
block.location  = rec.locid;

connections++;

block.save(function(err){

    if(err) throw err;
    //console.log('.');
    records_inserted++;

    if( --connections == 0 ){
        mongoose.disconnect();
        console.log( records_inserted + ' records inserted' );
    }

});

问题

由于文件是异步读取的,因此同时处理多行,读取文件比MongoDB写入快得多,因此整个过程停留在大约282000条记录,并且高达5k +并发Mongo连接。它不会崩溃..它只是坐在那里什么都不做,似乎没有恢复,mongo集合中的项目计数也没有进一步发展。

我在此之后是解决此问题的一般方法。我如何限制并发Mongo连接的数量?我想利用能够同时插入多个记录,但我错过了一种规范流量的方法。

提前谢谢。

2 个答案:

答案 0 :(得分:2)

不是您从.csv文件导入的确切情况的答案,而是在进行批量插入时

- >首先,没有特殊的“批量”插入操作,它最终都是forEach。

- >如果你试图读取一个异步的大文件,这比写入过程快得多,那么你应该考虑改变你的方法,首先要弄清楚你的设置能处理多少,(或者只是点击试验) )。

--->在那之后,改变你从文件中读取的方式,你不需要从文件中读取每一行,异步,学会等待,使用forEach,从Async.js forEachSeries将你的读取降低到接近mongodb写入级别,然后你很高兴。

答案 1 :(得分:1)

我会尝试Mongodb的命令行CSV导入选项 - 它应该做你想要的而不必编写任何代码