Mongoose v3.6+现在支持批量插入吗? 我搜索了几分钟,但是与此查询匹配的任何内容都有几年的历史,并且答案是明确的否定。
编辑:
供将来参考,答案是使用Model.create()
。 create()
接受数组作为其第一个参数,因此您可以将要插入的文档传递为数组。
Mongoose v3.6+现在支持批量插入吗? 我搜索了几分钟,但是与此查询匹配的任何内容都有几年的历史,并且答案是明确的否定。
编辑:
供将来参考,答案是使用Model.create()
。 create()
接受数组作为其第一个参数,因此您可以将要插入的文档传递为数组。
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()
。参数完全相同,因此您可以将其视为一种即插即用的替代方案,一切都应该能够正常工作(好吧,返回值有点不同,但您可能并没有真正使用它)。
Model.collection
直接通过Mongo驱动程序进行操作,因此您将失去所有精彩的mongoose功能,包括验证和钩子函数。这只是需要记住的一点。Model.create
会失去钩子函数,但仍然经过验证。如果您想拥有所有这些功能,您必须迭代并使用new MyModel()
。 - Pier-Luc GendreauMongoose 4.4.0引入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... */ });
你可以在下面链接中跟踪它:
bulkWrite
有什么不同?看这里:https://dev59.com/v1kT5IYBdhLWcg3wV-GZ#38743353 - Ondrej TokarinsertMany
比collection.insert
慢3-4倍,这可能是因为它将所有文档都返回给客户端。collection.insert
与pymongo insert_many
一样快 - https://stackoverflow.com/questions/58226391/mongoose-vs-pymongo-drivers-write-insertmany-test。 - Yuki确实,你可以使用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指出这一点)
{type:'jellybean'}
而不是 {type:'jelly bean'}
?顺便问一下,这些奇怪的类型是什么?它们是 Mongoose API 的一部分吗? - Stephan KristyninsertMany
和save
两种方式保存数据的方法。insertMany
以批量方式保存Mongoose文档数组。/* 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});
})
})
})
看起来使用mongoose时,当使用find()方法查询文档时,会有超过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);
});
}
/* 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);
}
}
您可以使用mongoDB shell执行批量插入,只需要将值插入到一个数组中即可。
db.collection.insert([{values},{values},{values},{values}]);
YourModel.collection.insert()
- Bill Dami分享我们项目中的可工作和相关代码:
//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);
});
Model.bulkWrite()
和Model.insertMany()
。 - Dan Dascalescu