首页 文章

猫鼬(mongodb)批量插入?

提问于
浏览
94

Mongoose v3.6+ 现在支持批量插入吗?我搜索了几分钟,但是这个查询的任何内容都是几年前的答案,答案是明确的 .

编辑:

为了将来参考,答案是使用 Model.create() . create() 接受数组作为其第一个参数,因此您可以将文档作为数组传递 .

Model.create() documentation

9 回答

  • 23

    您可以使用mongoose执行批量插入,作为最高分数答案 . 但是这个例子不行,应该是:

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

    不要使用模式实例进行批量插入,您应该使用普通的 Map 对象 .

  • 3

    似乎使用mongoose时,使用时有超过1000个文档的限制

    Potato.collection.insert(potatoBag, onInsert);
    

    您可以使用:

    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)
          });
    });
    

    但是,使用10000个文档进行测试时,这几乎快了两倍:

    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);
        });
    }
    
  • 2

    从我们的项目中共享工作和相关代码:

    //documentsArray is the list of sampleCollection objects
    sampleCollection.insertMany(documentsArray)  
        .then((res) => {
            console.log("insert sampleCollection result ", res);
        })
        .catch(err => {
            console.log("bulk insert sampleCollection error ", err);
        });
    
  • 1

    Mongoose 4.4.0现在支持批量插入

    Mongoose 4.4.0引入了--true--使用模型方法 .insertMany() 进行批量插入 . 它比在 .create() 上循环或为其提供数组更快 .

    用法:

    var rawDocuments = [/* ... */];
    
    Book.insertMany(rawDocuments)
        .then(function(mongooseDocuments) {
             /* ... */
        })
        .catch(function(err) {
            /* Error handling */
        });
    

    要么

    Book.insertMany(rawDocuments, function (err, mongooseDocuments) { /* Your callback function... */ });
    

    你可以跟踪它:

  • 3

    您可以使用插入数组中的值来使用mongoDB shell执行批量插入 .

    db.collection.insert([{values},{values},{values},{values}]);
    
  • 96

    Model.create()vs Model.collection.insert():一种更快的方法

    如果处理非常大的批量, Model.create() 是一种不好的方法 . 它将是 very slow . 在这种情况下,您应该使用 Model.collection.insert ,执行 much better . 根据批量的大小, Model.create() 甚至会崩溃!试过一百万份文件,没有运气 . 使用 Model.collection.insert 只花了几秒钟 .

    Model.collection.insert(docs, options, callback)
    
    • docs 是要插入的文档数组;

    • options 是可选配置对象 - 请参阅the docs
      保存所有文档或发生错误后将调用

    • callback(err, docs) . 成功时,docs是持久化文档的数组 .

    正如Mongoose的作者指出here,此方法将绕过任何验证程序并直接访问Mongo驱动程序 . 它's a trade-off you have to make since you'处理大量数据,否则你不会在这里说几十万个文件) .

    一个简单的例子

    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);
        }
    }
    

    参考

  • 5

    的确,你可以使用Mongoose的“create”方法,它可以包含一个文件数组,请看这个例子:

    Candy.create({ candy: 'jelly bean' }, { candy: 'snickers' }, function (err, jellybean, snickers) {
    });
    

    回调函数包含插入的文档 . 您并不总是知道必须插入多少项(固定参数长度如上),因此您可以循环它们:

    var insertedDocs = [];
    for (var i=1; i<arguments.length; ++i) {
        insertedDocs.push(arguments[i]);
    }
    

    更新:更好的解决方案

    一个更好的解决方案是使用 Candy.collection.insert() 而不是 Candy.create() - 在上面的例子中使用 - 因为它更快( create() 在每个项目上调用 Model.save() 所以它更慢) .

    有关更多信息,请参阅Mongo文档:http://docs.mongodb.org/manual/reference/method/db.collection.insert/

    (感谢arcseldon指出这一点)

  • 2

    我用async-forEach(link for async-forEach npm package documentation)来实现同样的目的 .

    我的代码片段如下所示 . 我在req.body中获取文档 .

    var forEach = require('async-foreach').forEach;    
    exports.save_Ctrl = function (req, res) {    
    //  var l=req.body;
    //  console.log("length:",l.length);
    
     forEach(req.body, function(item, index, object,err) {
    
        console.log(req.body[index]);
        var post = new saveObj(req.body[index]);   
    
            //save model to MongoDB
        post.save(function (err) {
            if (err) {
                console.log('error saving :' + err.message);
                return err;
            }   
            else {
                console.log("Post saved");
            }
        });       
    
      });    
     }
    
  • 137

    以下是使用insertMany和save保存数据的两种方法

    1)Mongoose保存 insertMany 批量文档

    /* write mongoose schema model and export this */
    var Potato = mongoose.model('Potato', PotatoSchema);
    
    /* write this api in routes directory  */
    router.post('/addDocuments', function (req, res) {
        const data = [/* array of object which data need to save in db */];
    
        Potato.insertMany(data)  
        .then((result) => {
                console.log("result ", result);
                res.status(200).json({'success': 'new documents added!', 'data': result});
        })
        .catch(err => {
                console.error("error ", err);
                res.status(400).json({err});
        });
    })
    

    2)Mongoose用 .save() 保存文件数组

    这些文件将保存并行 .

    /* write mongoose schema model and export this */
    var Potato = mongoose.model('Potato', PotatoSchema);
    
    /* write this api in routes directory  */
    router.post('/addDocuments', function (req, res) {
        const saveData = []
        const data = [/* array of object which data need to save in db */];
        data.map((i) => {
            console.log(i)
            var potato = new Potato(data[i])
            potato.save()
            .then((result) => {
                console.log(result)
                saveData.push(result)
                if (saveData.length === data.length) {
                    res.status(200).json({'success': 'new documents added!', 'data': saveData});
                }
            })
            .catch((err) => {
                console.error(err)
                res.status(500).json({err});
            })
        })
    })
    

相关问题