Mongoose (mongodb) batch insert?

后端 未结 8 1946
灰色年华
灰色年华 2020-11-27 10:15

Does Mongoose v3.6+ support batch inserts now? I\'ve searched for a few minutes but anything matching this query is a couple of years old and the answer was

相关标签:
8条回答
  • 2020-11-27 10:53

    It seems that using mongoose there is a limit of more than 1000 documents, when using

    Potato.collection.insert(potatoBag, onInsert);
    

    You can use:

    var bulk = Model.collection.initializeOrderedBulkOp();
    
    async.each(users, function (user, callback) {
        bulk.insert(hash);
    }, function (err) {
        var bulkStart = Date.now();
        bulk.execute(function(err, res){
            if (err) console.log (" gameResult.js > err " , err);
            console.log (" gameResult.js > BULK TIME  " , Date.now() - bulkStart );
            console.log (" gameResult.js > BULK INSERT " , res.nInserted)
          });
    });
    

    But this is almost twice as fast when testing with 10000 documents:

    function fastInsert(arrOfResults) {
    var startTime = Date.now();
        var count = 0;
        var c = Math.round( arrOfResults.length / 990);
    
        var fakeArr = [];
        fakeArr.length = c;
        var docsSaved = 0
    
        async.each(fakeArr, function (item, callback) {
    
                var sliced = arrOfResults.slice(count, count+999);
                sliced.length)
                count = count +999;
                if(sliced.length != 0 ){
                        GameResultModel.collection.insert(sliced, function (err, docs) {
                                docsSaved += docs.ops.length
                                callback();
                        });
                }else {
                        callback()
                }
        }, function (err) {
                console.log (" gameResult.js > BULK INSERT AMOUNT: ", arrOfResults.length, "docsSaved  " , docsSaved, " DIFF TIME:",Date.now() - startTime);
        });
    }
    
    0 讨论(0)
  • 2020-11-27 10:54

    Model.create() vs Model.collection.insert(): a faster approach

    Model.create() is a bad way to do inserts if you are dealing with a very large bulk. It will be very slow. In that case you should use Model.collection.insert, which performs much better. Depending on the size of the bulk, Model.create() will even crash! Tried with a million documents, no luck. Using Model.collection.insert it took just a few seconds.

    Model.collection.insert(docs, options, callback)
    
    • docs is the array of documents to be inserted;
    • options is an optional configuration object - see the docs
    • callback(err, docs) will be called after all documents get saved or an error occurs. On success, docs is the array of persisted documents.

    As Mongoose's author points out here, this method will bypass any validation procedures and access the Mongo driver directly. It's a trade-off you have to make since you're handling a large amount of data, otherwise you wouldn't be able to insert it to your database at all (remember we're talking hundreds of thousands of documents here).

    A simple example

    var Potato = mongoose.model('Potato', PotatoSchema);
    
    var potatoBag = [/* a humongous amount of potato objects */];
    
    Potato.collection.insert(potatoBag, onInsert);
    
    function onInsert(err, docs) {
        if (err) {
            // TODO: handle error
        } else {
            console.info('%d potatoes were successfully stored.', docs.length);
        }
    }
    

    Update 2019-06-22: although insert() can still be used just fine, it's been deprecated in favor of insertMany(). The parameters are exactly the same, so you can just use it as a drop-in replacement and everything should work just fine (well, the return value is a bit different, but you're probably not using it anyway).

    Reference

    • Mongo documentation
    • Aaron Heckman on Google Groups discussing bulk inserts
    0 讨论(0)
提交回复
热议问题