Du har to reelle valg her, alt efter hvordan du vil håndtere tingene:
-
Brug upsert funktionalitet af MongoDB til i det væsentlige at "slå op", hvis nøgledataene findes. Hvis ikke, så videregiver du kun data til
$setOnInsert
og det vil ikke røre noget andet. -
Brug "Ubestilte" operationer i bulk. Hele partiet af opdateringer fortsætter, selvom der returneres en fejl, men fejlrapporten(erne) er netop det, og alt, der ikke er en fejl, vil blive begået.
Helt eksempel:
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();
}
);
Bemærk, at den "ændrede handling" i aktuelle drivere er, at resultatsvaret på .execute()
vil returner et fejlobjekt, der skal kastes, hvor tidligere udgivelser ikke gjorde det med "Ikke-ordrede" operationer.
Dette gør det bydende nødvendigt, at din kode aldrig er afhængig af err
returneres alene, og du burde inspetere det returnerede result
i stedet for den fulde klassificering af fejl.
Ikke desto mindre, når den ikke er bestilt, fortsætter partiet indtil slutningen, uanset hvor mange fejl der opstår. Ting, der ikke er en fejl, vil blive begået som normalt.
Dette kommer virkelig ned til "er sekvens vigtig". Hvis ja, så har du brug for "Bestilte" operationer, og du kan kun undgå duplikerede nøgler ved at bruge "upserts". Ellers brug "uordnet", men vær opmærksom på fejlen, og hvad de rent faktisk betyder.
Også når du bruger .collection
for at få det underliggende samlingsobjekt fra basisdriveren til at aktivere "Bulk"-operationer, skal du altid være sikker på, at enten "en eller anden" mongoose-metode altid er blevet kaldt først.
Uden det er der ingen garanteret forbindelse til databasen med de native driver-metoder, da den håndteres for mongoose-metoderne, så operationen vil mislykkes på grund af ingen forbindelse.
Alternativet til at "affyre" en mangustmetode først, er at pakke din applogik ind i en begivenhedslytter for forbindelsen:
mongoose.connection.on("open",function(err) {
// app logic in here
})