Mongoose v3.6 + 现在是否支持批量插入?我已经搜索了几分钟,但是这个查询的任何内容都已经过了几年,答案是明确的。
编辑:
为了将来参考,答案是使用Model.create()
。 create()
接受一个数组作为其第一个参数,因此您可以将文档作为数组传递。
答案 0 :(得分:145)
Model.create()
是一种不好的方法。它将非常慢。在这种情况下,您应该使用Model.collection.insert
,这会更好地执行 。根据批量大小,Model.create()
甚至会崩溃!试过一百万份文件,没有运气。使用Model.collection.insert
只花了几秒钟。
Model.collection.insert(docs, options, callback)
docs
是要插入的文档数组; options
是可选的配置对象 - 请参阅the docs callback(err, docs)
。成功时,docs是持久化文档的数组。正如Mongoose的作者指出here,此方法将绕过任何验证程序并直接访问Mongo驱动程序。这是你必须要做的权衡,因为你正在处理大量的数据,否则你根本无法将它插入你的数据库(请记住我们在这里谈论成千上万的文档)。 / p>
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);
}
}
答案 1 :(得分:105)
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... */ });
您可以在以下位置进行跟踪:
答案 2 :(得分:23)
确实,您可以使用"创建" Mongoose的方法,它可以包含一个文档数组,参见这个例子:
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()
上调用{{1}}项目,所以它慢了。)
有关更多信息,请参阅Mongo文档: http://docs.mongodb.org/manual/reference/method/db.collection.insert/
(感谢 arcseldon 指出这一点)
答案 3 :(得分:5)
您可以使用插入数组中的值来使用mongoDB shell执行批量插入。
db.collection.insert([{values},{values},{values},{values}]);
答案 4 :(得分: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);
}
}
不要使用模式实例进行批量插入,您应该使用普通的地图对象。
答案 5 :(得分: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);
});
}
答案 6 :(得分: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");
}
});
});
}
答案 7 :(得分:2)
以下是使用insertMany保存数据和保存
的两种方法 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});
})
})
})
答案 8 :(得分:1)
从我们的项目中分享工作和相关代码:
//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);
});