以下是相关代码:
var Results = mongoose.model('Results', resultsSchema);
var results_array = [];
_.each(matches, function(match) {
var results = new Results({
id: match.match_id,
... // more attributes
});
results_array.push(results);
});
callback(results_array);
});
}
], function(results_array) {
results_array.insert(function(err) {
// error handling
当然,我为No method found
获得results_array
。但是我不确定还有什么可以调用这个方法。
在其他函数中,我在这里传递等效的results
变量,这是一个猫鼬对象并且有insert
方法可用。
如何在此处插入文档数组?
**编辑**
function(results_array) {
async.eachLimit(results_array, 20, function(result, callback) {
result.save(function(err) {
callback(err);
});
}, function(err) {
if (err) {
if (err.code == 11000) {
return res.status(409);
}
return next(err);
}
res.status(200).end();
});
});
所以发生了什么:
当我清除收藏品时,这很好用。 但是,当我重新发送此请求时,我从未收到回复。
这种情况正在发生,因为我的架构不允许来自JSON响应的重复项。因此,当我重新发送请求时,它获得与第一个请求相同的数据,因此会响应错误。这就是我认为状态代码409
处理的内容。
我的实施中是否存在拼写错误?
修改2
出现错误代码:
{ [MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index:
test.results.$_id_ dup key: { : 1931559 }]
name: 'MongoError',
code: 11000,
err: 'insertDocument :: caused by :: 11000 E11000 duplicate key error index:
test.results.$_id_ dup key: { : 1931559 }' }
所以这是预期的。 Mongo正在回复11000错误,抱怨这是一个重复的密钥。
编辑3
if (err.code == 11000) {
return res.status(409).end();
}
这似乎解决了这个问题。这是一个创可贴修复吗?
答案 0 :(得分:1)
您似乎在尝试一次插入各种文档。所以你实际上有几个选择。
首先,mongoose中没有.insert()
方法,因为它被其他包装替换为.save()
和.create()
。这里最基本的过程是在刚刚创建的每个文档上调用“save”。同时在这里使用async库来实现一些流控制,这样一切都不会排队:
async.eachLimit(results_array,20,function(result,callback) {
result.save(function(err) {
callback(err)
});
},function(err) {
// process when complete or on error
});
另一件事是.create()
只能将对象列表作为参数,并在创建文档时简单地插入每个对象:
Results.create(results_array,function(err) {
});
实际上,这将是“原始”对象,因为它们基本上都是作为mongooose文档首先被投射。您可以在回调签名中将这些文档作为附加参数请求,但构建该文件可能有点过分。
无论哪种方式摇动,“异步”形式将并行处理,“创建”形式将按顺序处理,但它们都有效地为每个创建的文档向数据库发出一个“插入”。 / p>
对于真正的批量功能,您目前需要解决基础驱动程序方法,最佳位置是Bulk Operations API:
mongoose.connection.on("open",function(err,conn) {
var bulk = Results.collection.initializeUnorderedBulkOp();
var count = 0;
async.eachSeries(results_array,function(result,callback) {
bulk.insert(result);
count++;
if ( count % 1000 == 0 ) {
bulk.execute(function(err,response) {
// maybe check response
bulk = Results.collection.initializeUnorderedBulkOp();
callback(err);
});
} else {
callback();
}
},function(err) {
// called when done
// Check if there are still writes queued
if ( count % 1000 != 0 )
bulk.execute(function(err,response) {
// maybe check response
});
});
});
此处的数组同样是原始对象,而不是那些被转换为mongoose文档的对象。这里没有实现验证或其他mongoose模式逻辑,因为这只是一个基本的驱动方法,并且不知道这些事情。
虽然数组是串行处理的,但上面显示只有每1000个条目处理或到达结束时,写操作才会实际发送到服务器。所以这确实会立即将所有内容发送到服务器。
无序操作意味着通常不会设置err
,而“响应”文档将包含可能发生的任何错误。如果您希望第一个错误失败,那么它将是.initializeOrderedBulkOp()
。
这里需要注意的是,在以这种方式访问这些方法之前,必须确保连接已打开。 Mongoose使用它自己的方法来查看连接,因此在对数据库进行实际连接之前,在代码中达到诸如.save()
之类的方法,它在等待此事件的意义上“排队”。
因此要么确保首先完成其他“mongoose”操作,要么确保您的应用程序逻辑在确保连接的情况下工作。在此示例中通过放置在“连接打开”事件中进行模拟。
这取决于你真正想做的事情。每个案例都有它的用途,当然最后一个是最快的方式,因为有限的“写”和“返回结果”对话与服务器来回传递。