你有两个真正的选择,这取决于你想如何处理事情:
使用 MongoDB 的upsert 功能基本上“查找”关键数据是否存在。如果没有,那么您只需将数据传递给$setOnInsert,这不会涉及任何其他内容。
批量使用“UnOrdered”操作。即使返回错误,整批更新也会继续,但错误报告就是这样,任何不是错误的都会被提交。
整个例子:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
var testSchema = new Schema({
"_id": Number,
"name": String
},{ "_id": false });
var Test = mongoose.model('Test',testSchema,'test');
mongoose.connect('mongodb://localhost/test');
var data = [
{ "_id": 1, "name": "One" },
{ "_id": 1, "name": "Another" },
{ "_id": 2, "name": "Two" }
];
async.series(
[
// Start fresh
function(callback) {
Test.remove({},callback);
},
// Ordered will fail on error. Upserts never fail!
function(callback) {
var bulk = Test.collection.initializeOrderedBulkOp();
data.forEach(function(item) {
bulk.find({ "_id": item._id }).upsert().updateOne({
"$setOnInsert": { "name": item.name }
});
});
bulk.execute(callback);
},
// All as expected
function(callback) {
Test.find().exec(function(err,docs) {
console.log(docs)
callback(err);
});
},
// Start again
function(callback) {
Test.remove({},callback);
},
// Unordered will just continue on error and record an error
function(callback) {
var bulk = Test.collection.initializeUnorderedBulkOp();
data.forEach(function(item) {
bulk.insert(item);
});
bulk.execute(function(err,result) {
callback(); // so what! Could not care about errors
});
},
// Still processed the whole batch
function(callback) {
Test.find().exec(function(err,docs) {
console.log(docs)
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
请注意,当前驱动程序中的“更改操作”是.execute() 上的结果响应将返回要抛出的错误对象,而以前的版本没有使用“无序" 操作。
这使得您的代码绝对不能单独依赖返回的err,并且您应该输入返回的result,而不是对错误进行完整分类。
尽管如此,当无序时,无论发生多少错误,批处理都会持续到最后。不是错误的事情将照常提交。
这真的归结为“序列是否重要”。如果是这样,那么您需要“有序”操作,并且只能通过使用“upserts”来避免重复键。否则使用“无序”,但要注意错误返回及其实际含义。
此外,当使用.collection 从基础驱动程序获取底层集合对象以启用“批量”操作时,请始终确保始终首先调用“某些”猫鼬方法。
否则,无法保证使用本机驱动程序方法连接到数据库,因为它是为 mongoose 方法处理的,因此操作将由于没有连接而失败。
首先“触发” mongoose 方法的替代方法是将您的应用程序逻辑包装在连接的事件侦听器中:
mongoose.connection.on("open",function(err) {
// app logic in here
})