在mongodb中一一插入50万条记录会导致堆内存不足

时间:2019-10-01 13:48:02

标签: javascript node.js mongodb express mongoose

我试图在mongodb中插入500 000条记录记录 采集。这些值存储在csv中并进行解析,然后存储到数组中。使用递归函数一个接一个地插入记录,当再次插入一个记录时,将调用相同的函数。 此过程适用于20万条记录,但是当记录大小增加到20万以上时,会导致堆内存不足(JS堆栈跟踪)。

下面是我正在使用的递归函数

function insertMongoSingle(fileRows, x, total){
    if(x < total){
        let item = fileRows.shift();
        let record  = new Record({i:item}, false);
        record.save(function(error, contact){
            if(error){
                console.log(error);
                x++;
                insertMongoSingle(fileRows, x ,total);
            }else{
                x++;
                insertMongoSingle(fileRows, x, total);
            }
        }); 
    }else{
        console.log('completed');
    }
}

其中x是计数,fileRows是对象数组中的总记录,而total是fileRows的长度

2 个答案:

答案 0 :(得分:1)

您是否不能选择使用命令行导入CSV数据?如果有的话,使用mongoimport是更好的选择。如果不是这样,并且想要在保存到数据库之前解析和自定义数据,则可以使用CSV流解析器。批量收集和处理记录。假设每个批次都有5000条记录,用Model.insertMany(records)插入每个批次,刷新它并创建一个新批次,进行处理并重复直到完成所有批次(记录)。

mongoimport

 mongoimport -d dbname -c collectionName --type csv --file input.csv --headerline

以编程方式:

const csv = require('fast-csv');
const fs =   require('fs')
let records = [];
let limits = 5000
fs.createReadStream('my.csv')
    .pipe(csv.parse({ headers: true}))
    .on('error', error => console.error(error))
    .on('data', row => {
         // customize your data here 
        records.push(row);
       if(recors.legth==limits) {
       Model.insertMany(records)
       records = [];
      }
     })
    .on('end', rowCount => {
   });

答案 1 :(得分:0)

  

我建议您使用bulk insert mongo功能。

已经对stackoverflow给出了详细的答案:Inserting a big array of object in mongodb from nodejs

或者,如果您需要其他解决方案,可以查看我的加载示例: Loading 10K of seed data