如何在带有NodeJS的MongoDB中使用批处理过程插入数百万个文档

时间:2018-12-17 22:09:06

标签: node.js mongodb

我已经编写了nodejs脚本来读取JSON文件,并将多条记录插入mongo集合中,我有数百万条记录,并且我不想在短时间内插入所有文档。我想每秒插入300个文档并休眠30秒,然后再插入300个,依此类推?我是NodeJS的新手,请问我如何用下面的代码实现这一目标?感谢您的帮助和支持。

app.js

const mongoClient = require("mongodb").MongoClient;
const util = require('util');
const fs = require('fs');

let database = null;
new mongoClient('mongodb://localhost:3000/', {
    auth: {
        user: 'admin',
        password: 'password',
    }
}).connect(
    (err, db) => {
        if (err) return console.error(err);
        database = db.db('myDB');
        fs.readFile('data.json', 'utf8', function(err, data) {
            if (err) throw err;
            var json = JSON.parse(data);
            database.collection("test").insertMany(json, function(err, doc) {
                console.log("Documents inserting");
                if (err) throw err;
            });
            //db.close();
        });
    });

示例数据:-我在单个文件中有数百万条这样的记录。

 [{
    "firstName": "Ariel",
    "lastName": "Bailey"
 }, {
    "firstName": "Lura",
    "lastName": "Buckridge"
 }, {
    "firstName": "Milton",
    "lastName": "Macejkovic"
 }, {
    "firstName": "Carolyn",
    "lastName": "Hegmann"
 }, {
    "firstName": "Sid",
    "lastName": "Beer"
 }]

2 个答案:

答案 0 :(得分:1)

这是您想要获得的基本概念。老实说,它不是100%完美,其余的是您的努力。

var ids = 0, offset = 10000;

function readJson() {
    var json = /* read JSON file */;
    return json;
}

function splitWithBatch(ids, offset) {
    var jsonObj = {};
    for(var i = ids; i < offset; i++){
        jsonObj.push(json[i]);
    }
    return Q.resolve(jsonObj);
}

function callSending(ids) {
    return splitWithBatch(ids, 0).then(ProcessToSave);
}

function ProcessToSave(json) {
    var quantityLimit = 1000;
    return SendToMongo(json).then(doNextBatch);
    function doNextBatch() {
        if (json.length === quantityLimit) {
            return splitWithBatch(ids, offset + quantityLimit);
        } else {
            return Q.resolve(null);
        }
    }
}

function SendToMongo(json) {
    database.collection('test').insertMany(json, function(err, doc) {
        if (err) throw err;
    });
}

readJson().then(callSending).then(
    function(){
        console.log('done');
    },
    function (err){
        console.log('err', err.stack, err);
    }
);

答案 1 :(得分:1)

您可以使用setTimeout来“分批”您的插入内容,如下所示:

fs.readFile('data.json', 'utf8', function (err, data) {
  if (err) throw err;
  var json = JSON.parse(data);
  processRecords(0, 300, 30 * 1000);

  function processRecords(startIdx, n, delay) {
    if (startIdx >= json.length) return db.close();

    database.collection("test").insertMany(json.slice(startIdx, startIdx + n), function (err, doc) {
      if (err) throw err;

      setTimeout(() => processRecords(startIdx + n, n, delay), delay);
    });
  }
});