sql >> Databáze >  >> NoSQL >> MongoDB

Chyba duplicitního klíče Mongoose s upsertem

Upsert, jehož výsledkem je vložení dokumentu, není plně atomická operace. Představte si, že upsert provádí následující samostatné kroky:

  1. Dotaz na identifikovaný dokument, který má být aktualizován.
  2. Pokud dokument existuje, atomicky aktualizujte existující dokument.
  3. Jinak (dokument neexistuje), atomicky vložte nový dokument, který obsahuje pole dotazu a aktualizaci.

Kroky 2 a 3 jsou tedy atomické, ale po kroku 1 může dojít k dalšímu upsert, takže váš kód musí zkontrolovat chybu duplicitního klíče a poté opakovat upsert, pokud k tomu dojde. V tu chvíli znáte dokument s tímto _id existuje, takže vždy uspěje.

Například:

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

Zde naleznete související dokumentaci.

Možná se stále ptáte, proč se to může stát, pokud je vložka atomická, ale to znamená, že ve vloženém dokumentu nedojde k žádným aktualizacím, dokud nebude zcela napsán, nikoli že žádná jiná vložka dokumentu se stejným _id může dojít.

Také nemusíte ručně vytvářet index na _id protože všechny kolekce MongoDB mají jedinečný index na _id bez ohledu na. Takže můžete odstranit tento řádek:

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



  1. Jak provedu dotaz na pole id v Mongoose?

  2. Jak znovu použít připojení mongodb prostřednictvím Promise

  3. MongoDB - Vytvořte vztah

  4. Příprava serveru MongoDB pro produkci