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); } }
不要使用模式实例进行批量插入,您应该使用普通的映射对象。