sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongoose duplikatnøglefejl med upsert

En upsert, der resulterer i en dokumentindsættelse, er ikke en fuldstændig atomart operation. Tænk på upsert som at udføre følgende diskrete trin:

  1. Forespørgsel om, at det identificerede dokument skal ophæves.
  2. Hvis dokumentet eksisterer, skal du atomisk opdatere det eksisterende dokument.
  3. Ellers (dokumentet findes ikke), indsæt atomisk et nyt dokument, der inkorporerer forespørgselsfelterne og opdateringen.

Så trin 2 og 3 er hver atomare, men en anden upsert kan forekomme efter trin 1, så din kode skal tjekke for duplikatnøglefejlen og derefter prøve upsert igen, hvis det sker. På det tidspunkt kender du dokumentet med det _id eksisterer, så det vil altid lykkes.

For eksempel:

var minute = utils.minute();
Monitor.update({ _id: minute }, { $inc: update }, { upsert: true }, function(err) {
    if (err) {
        if (err.code === 11000) {
            // Another upsert occurred during the upsert, try again. You could omit the
            // upsert option here if you don't ever delete docs while this is running.
            Monitor.update({ _id: minute }, { $inc: update }, { upsert: true },
                function(err) {
                    if (err) {
                        console.trace(err);
                    }
                });
        }
        else {
            console.trace(err);
        }
    }
});

Se her for den relaterede dokumentation.

Du undrer dig måske stadig over, hvorfor dette kan ske, hvis indsættelsen er atomær, men det betyder, at der ikke vil ske opdateringer på det indsatte dokument, før det er fuldstændigt skrevet, ikke at der ikke er nogen anden indsættelse af et dokument med samme _id kan forekomme.

Du behøver heller ikke manuelt at oprette et indeks på _id da alle MongoDB-samlinger har et unikt indeks på _id uanset. Så du kan fjerne denne linje:

monitorSchema.index({_id: -1}); // Not needed



  1. MongoDB prik (.) i nøglenavn

  2. vent på, at alle løfter er færdige i nodejs med bluebird

  3. Hvorfor kan jeg ikke køre lua script i redis efter redis genstart?

  4. MongoDB $loft