Hoa*_*Hoa 66 mongoose mongodb node.js
目前我使用save来添加单个文档.假设我有一个文档数组,我希望将其存储为单个对象.有没有办法通过单个函数调用添加它们,然后在完成后获得单个回调?我可以单独添加所有文档,但是管理回调以便在完成所有操作时解决问题.
Pas*_*jac 88
Mongoose现在支持将多个文档结构传递给Model.create.引用他们的API示例,它支持传递一个数组或一个varargs对象列表,最后带有一个回调:
Candy.create({ type: 'jelly bean' }, { type: 'snickers' }, function (err, jellybean, snickers) {
if (err) // ...
});
Run Code Online (Sandbox Code Playgroud)
要么
var array = [{ type: 'jelly bean' }, { type: 'snickers' }];
Candy.create(array, function (err, jellybean, snickers) {
if (err) // ...
});
Run Code Online (Sandbox Code Playgroud)
编辑:正如许多人所说,这不会执行真正的批量插入 - 它只是隐藏了save
自己多次调用的复杂性.下面有答案和评论解释如何使用实际的Mongo驱动程序来实现批量插入以保证性能.
Pie*_*eau 46
Mongoose 4.4添加了一个名为的方法 insertMany
验证文档数组并将其插入MongoDB的快捷方式(如果它们全部有效).此函数比.create()更快,因为它只向服务器发送一个操作,而不是每个文档发送一个操作.
从问题#723引用vkarpov15 :
权衡是insertMany()不会触发预保存挂钩,但它应该具有更好的性能,因为它只对数据库进行1次往返,而不是每个文档1次.
该方法的签名与以下内容相同create
:
Model.insertMany([ ... ], (err, docs) => {
...
})
Run Code Online (Sandbox Code Playgroud)
或者,承诺:
Model.insertMany([ ... ]).then((docs) => {
...
}).catch((err) => {
...
})
Run Code Online (Sandbox Code Playgroud)
小智 36
Mongoose还没有实现批量插入(参见问题#723).
既然您知道要保存的文档数量,就可以这样写:
var total = docArray.length
, result = []
;
function saveAll(){
var doc = docArray.pop();
doc.save(function(err, saved){
if (err) throw err;//handle error
result.push(saved[0]);
if (--total) saveAll();
else // all saved here
})
}
saveAll();
Run Code Online (Sandbox Code Playgroud)
当然,这是一个临时解决方案,我建议使用某种流量控制库(我使用q,它很棒).
cyb*_*bat 25
Mongoose中的批量插入可以使用.insert()完成,除非您需要访问中间件.
Model.collection.insert(docs, options, callback)
https://github.com/christkv/node-mongodb-native/blob/master/lib/mongodb/collection.js#L71-91
Chr*_*ren 12
使用async parallel,您的代码将如下所示:
async.parallel([obj1.save, obj2.save, obj3.save], callback);
Run Code Online (Sandbox Code Playgroud)
由于Mongoose中的约定与async(错误,回调)中的约定相同,因此您无需将它们包装在自己的回调中,只需在数组中添加保存调用即可在完成所有操作后获得回调.
如果使用mapLimit,则可以控制要并行保存的文档数.在此示例中,我们将并行保存10个文档,直到所有项目都成功保存.
async.mapLimit(myArray, 10, function(document, next){
document.save(next);
}, done);
Run Code Online (Sandbox Code Playgroud)
我知道这是一个老问题,但它让我担心这里没有正确的答案.大多数答案只是讨论迭代所有文档并单独保存每个文档,如果您有多个文档,这是一个不好的想法,并且在许多请求中甚至会重复该过程.
MongoDB特别batchInsert()
要求插入多个文档,这应该从本机mongodb驱动程序中使用.Mongoose是基于此驱动程序构建的,它不支持批量插入.它可能是有道理的,因为它应该是MongoDB的Object文档建模工具.
解决方案:Mongoose附带本机MongoDB驱动程序.您可以通过要求它来使用该驱动程序require('mongoose/node_modules/mongodb')
(对此不太确定,但如果它不起作用,您可以再次安装mongodb npm,但我认为应该这样做)然后做一个正确的batchInsert
使用insertMany
函数插入多个文档。这只会向服务器发送一项操作,并Mongoose
在到达 mongo 服务器之前验证所有文档。默认情况下,按照Mongoose
项目在数组中存在的顺序插入项目。如果您同意不维持任何订单,请设置ordered:false
。
重要 - 错误处理:
当ordered:true
验证和错误处理发生在一组中时,意味着如果其中一个失败,那么一切都会失败。
当ordered:false
验证和错误处理单独发生时,操作将继续。错误将以错误数组的形式报告回来。
较新版本的MongoDB支持批量操作:
var col = db.collection('people');
var batch = col.initializeUnorderedBulkOp();
batch.insert({name: "John"});
batch.insert({name: "Jane"});
batch.insert({name: "Jason"});
batch.insert({name: "Joanne"});
batch.execute(function(err, result) {
if (err) console.error(err);
console.log('Inserted ' + result.nInserted + ' row(s).');
}
Run Code Online (Sandbox Code Playgroud)
这是另一种不使用其他库的方法(不包括错误检查)
function saveAll( callback ){
var count = 0;
docs.forEach(function(doc){
doc.save(function(err){
count++;
if( count == docs.length ){
callback();
}
});
});
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
94951 次 |
最近记录: |