129

Mongoose v3.6+现在支持批量插入吗?我已经搜索了几分钟,但与此查询匹配的任何内容都是几年前的,答案是明确的不。

编辑:

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

请参阅Model.create() 文档

4

8 回答 8

179

Model.create() 与 Model.collection.insert():更快的方法

Model.create()如果您正在处理非常大的批量,那么插入是一种不好的方法。它会很慢。在这种情况下,您应该使用Model.collection.insert它,它的性能要好得多。根据散装的大小,Model.create()甚至会崩溃!尝试了一百万个文件,没有运气。使用Model.collection.insert它只需几秒钟。

Model.collection.insert(docs, options, callback)
  • docs是要插入的文档数组;
  • options是一个可选的配置对象 - 请参阅文档
  • callback(err, docs)将在所有文档保存或发生错误后调用。成功时, docs 是持久化文档的数组。

正如 Mongoose 的作者在这里指出的那样,这种方法将绕过任何验证程序并直接访问 Mongo 驱动程序。这是您必须做出的权衡,因为您要处理大量数据,否则您根本无法将其插入到您的数据库中(请记住,我们在这里讨论的是数十万个文档)。

一个简单的例子

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

2019-06-22 更新:虽然insert()仍然可以正常使用,但它已被弃用,取而代之的是insertMany(). 参数完全相同,因此您可以将其用作直接替换,并且一切都应该正常工作(嗯,返回值有点不同,但您可能无论如何都不会使用它)。

参考

于 2014-07-20T06:54:58.867 回答
123

Mongoose 4.4.0 现在支持批量插入

Mongoose 4.4.0 引入了 --true--bulk insert 和 model 方法.insertMany()。它比循环.create()或为其提供数组要快得多。

用法:

var rawDocuments = [/* ... */];

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

或者

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

您可以在以下位置进行跟踪:

于 2016-02-03T10:38:03.960 回答
22

事实上,你可以使用 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指出这一点)

于 2014-03-29T20:30:15.127 回答
6

这是使用 insertMany 和 save 保存数据的两种方式

insertMany1)猫鼬批量保存文档数组

/* 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)猫鼬保存文档数组.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});
        })
    })
})
于 2018-05-16T17:36:33.920 回答
4

您可以使用 mongoDB shell 通过在数组中插入值来执行批量插入。

db.collection.insert([{values},{values},{values},{values}]);
于 2014-08-08T09:03:30.020 回答
4

您可以使用 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);
    }
}

不要为批量插入使用模式实例,您应该使用普通的地图对象。

于 2015-03-16T03:35:28.700 回答
4

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);
    });
}
于 2015-08-02T18:37:55.290 回答
0

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

//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);
    });
于 2017-12-26T17:01:18.087 回答