Тук имате два реални избора в зависимост от това как искате да се справите с нещата:
-
Използвайте upsert функционалността на MongoDB по същество да „търси“, ако ключовите данни съществуват. Ако не, тогава предавате данни само на
$setOnInsert
и това няма да докосне нищо друго. -
Използвайте „Неподредени“ операции групово. Цялата партида от актуализации ще продължи дори ако се върне грешка, но отчетът(ите) за грешка са точно това и всичко, което не е грешка, ще бъде извършено.
Цял пример:
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 е да обвиете логиката на приложението си в слушател на събития за връзката:
mongoose.connection.on("open",function(err) {
// app logic in here
})