mongoose(mongodb)批量插入?

Mongoose v3.6 +支持批量插入吗? 我已经search了几分钟,但是与这个查询匹配的任何东西都是几十年,答案是一个明确的不。

编辑:

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

请参阅http://mongoosejs.com/docs/api.html#model_Model.create

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

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

 Model.collection.insert(docs, options, callback) 
  • docs是要插入的文档的数组;
  • options是一个可选的configuration对象 – 请参阅文档
  • callback(err, docs)将在所有文档保存或发生错误后被调用。 成功的时候,文档就是一连串的文档。

正如Mongoose的作者在这里指出的那样,这种方法将绕过任何validation过程并直接访问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); } } 

参考

  • Mongo文档
  • Google小组的Aaron Heckman讨论批量插入

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... */ }); 

你可以追踪它:

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

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

callback函数包含插入的文档。 你并不总是知道需要插入多less项(像上面那样固定的参数长度),所以你可以循环它们:

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

更新:更好的解决scheme

更好的解决scheme是使用Candy.collection.insert()而不是Candy.create() – 在上面的例子中使用 – 因为速度更快( create() Model.save()在每个项目上调用Model.save() ,所以速度更慢)。

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

(感谢arcseldon指出这一点)

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

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

使用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个文档进行testing的速度几乎快了一倍:

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

我使用async-forEach( async-forEach npm包文档的链接 )来实现相同。

我的代码片段如下所示。我正在获取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"); } }); }); } 

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

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