sql >> Database >  >> NoSQL >> MongoDB

Mongoose dubbele sleutelfout met upsert

Een upsert die resulteert in een documentinvoeging is geen volledig atomaire operatie. Beschouw de upsert als het uitvoeren van de volgende discrete stappen:

  1. Vraag om het geïdentificeerde document om op te heffen.
  2. Als het document bestaat, werkt u het bestaande document atomair bij.
  3. Anders (het document bestaat niet), voeg atomair een nieuw document in dat de zoekvelden en de update bevat.

Dus stappen 2 en 3 zijn elk atomair, maar er kan nog een upsert optreden na stap 1, dus uw code moet controleren op de dubbele sleutelfout en vervolgens de upsert opnieuw proberen als dat gebeurt. Op dat moment ken je het document met die _id bestaat, dus het zal altijd slagen.

Bijvoorbeeld:

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);
        }
    }
});

Zie hier voor de bijbehorende documentatie.

Je vraagt ​​​​je misschien nog steeds af waarom dit kan gebeuren als de invoeging atomair is, maar wat dat betekent is dat er geen updates zullen plaatsvinden op het ingevoegde document totdat het volledig is geschreven, niet dat er geen andere invoeging van een document met dezelfde _id kan voorkomen.

U hoeft ook niet handmatig een index te maken op _id aangezien alle MongoDB-collecties een unieke index hebben op _id achteloos. U kunt deze regel dus verwijderen:

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



  1. De top 6 gratis Redis-geheugenanalysetools

  2. Verschil tussen op documenten gebaseerde en op sleutel/waarde gebaseerde databases?

  3. Hoe krijg ik toegang tot een reeds bestaande collectie met Mongoose?

  4. $wind een object af in het aggregatieraamwerk