如何使用Node JS在MongoDb中更快地插入100万条记录?

时间:2018-02-13 06:49:57

标签: javascript node.js mongodb

我有复制和粘贴以实现100万条记录。有更快的方法吗?我不能在for..loop中使用100000。 Window 10的命令提示符将为forzen。

var MongoClient = require('mongodb').MongoClient,
    assert = require('assert');

var colName = 'students';
MongoClient.connect('mongodb://localhost:27017/school', function(err, db) {
    assert.equal(err, null);
    console.log("Successfully connected to MongoDB.");

    var collection = db.collection(colName);

    db.listCollections().toArray(function(err, collections) {
            if (err) console.log(err);

            var result = collections.some(function(coll) {
                if (coll.name == colName) {
                    return true;
                }
            });

            if (result) {
                console.log(colName+" FOUND.");
                collection.drop(function(err, delOK) {
                    if (err) throw err;
                    if (delOK) console.log(colName+" Collection deleted");
                    db.close();
                });             
            } else {
                console.log("NOT FOUND.");
                db.close();
            }
        });
});

var fc = 10000;
var counter = 0;

//create 10,000 records
function inputStudents(lastCount) {
    MongoClient.connect('mongodb://localhost:27017/school', function(err, db) {
        assert.equal(err, null);
        console.log("Successfully connected to MongoDB.");

        var collection = db.collection(colName);
        var types = ['exam', 'quiz', 'homework', 'homework'];

        var maxReq = 10000;
        var finalCount = lastCount * 10;

        // 10,000 students
        for (i = 0; i < maxReq; i++) {

            // take 10 classes
            for (class_counter = 0; class_counter < 10; class_counter ++) {
                scores = []
                    // and each class has 4 grades
                    for (j = 0; j < 4; j++) {
                        scores.push({'type':types[j],'score':Math.random()*100});
                    }

                // there are 500 different classes that they can take
                class_id = Math.floor(Math.random()*501); // get a class id between 0 and 500

                record = {'student_id':i, 'scores':scores, 'class_id':class_id};
                collection.insertOne(record, function(err, res) {
                        if (err) throw err;
                        counter++;
                        console.log("counter: "+counter);
                        if (counter == finalCount) db.close();
                    });
            }
        }   
    });
}

//wait 10 seconds, 1
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 10000);

//wait 2m, 2
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 2*60*1000);

//wait 4m, 3
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 4*60*1000);

//wait 6m, 4
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 6*60*1000);

//wait 8m, 5
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 8*60*1000);

//wait 10m, 6
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 10*60*1000);

//wait 12m, 7
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 12*60*1000);

//wait 14m, 8
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 14*60*1000);

//wait 16m, 9
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 16*60*1000);

//wait 18m, 10
setTimeout(function afterTenSeconds() {
    inputStudents(fc+counter);
}, 18*60*1000);

我必须复制并粘贴每一个,2分钟的差距。有没有办法连接回调?我不能让他们同时跑。我会得到&lt; 100万条记录,因为db.close会删除一些记录。

1 个答案:

答案 0 :(得分:1)

您可以使用bulk插页。

有两种类型的批量操作:

  1. 订购批量操作。这些操作按顺序执行所有操作,并在第一次写入错误时执行错误。

  2. 无序批量操作。这些操作并行执行所有操作并聚合所有错误。无序批量操作不保证执行顺序。

  3. 所以你可以这样做:

    var MongoClient = require('mongodb').MongoClient;
    
    MongoClient.connect("mongodb://myserver:27017/test", function(err, db) {
    // Get the collection
    var col = db.collection('myColl');
    
    // Initialize the Ordered Batch
    // You can use initializeUnorderedBulkOp to initialize Unordered Batch
    var batch = col.initializeOrderedBulkOp();
    
    // take 10 classes
            for (class_counter = 0; class_counter < 10; class_counter ++) {
                scores = []
                    // and each class has 4 grades
                    for (j = 0; j < 4; j++) {
                        scores.push({'type':types[j],'score':Math.random()*100});
                    }
    
                // there are 500 different classes that they can take
                class_id = Math.floor(Math.random()*501); // get a class id between 0 and 500
    
                record = {'student_id':i, 'scores':scores, 'class_id':class_id};
      batch.insert(record);
    }
    
    // Execute the operations
    batch.execute(function(err, result) {
      console.dir(err);
      console.dir(result);
      db.close();
    });
    });
    

    我的意思是这样的,我没有执行代码,所以我不确定它会起作用,但你会理解我想说的。

    希望这有帮助!