MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Mungo:Erkenne, ob das eingefügte Dokument ein Duplikat ist, und gib das vorhandene Dokument zurück, wenn dies der Fall ist

Während Ihr Code einige Fehlerfälle nicht behandelt und den falschen find verwendet Funktion, der allgemeine Ablauf ist typisch für die Arbeit, die Sie erledigen möchten.

  1. Wenn andere Fehler als das Duplikat vorhanden sind, wird der Rückruf nicht aufgerufen, was wahrscheinlich nachgelagerte Probleme in Ihrer NodeJs-Anwendung verursachen wird
  2. verwenden Sie findOne statt find da es nur ein Ergebnis geben wird, wenn der Schlüssel eindeutig ist. Andernfalls wird ein Array zurückgegeben.
  3. Wenn Ihr Rückruf den traditionellen error erwartet hat Als erstes Argument könnten Sie den Rückruf direkt an findOne übergeben Funktion, anstatt eine anonyme Funktion einzuführen.
  4. Sie können sich auch findOneAndUpdate ansehen schließlich, je nachdem, wie Ihr endgültiges Schema und Ihre Logik aussehen werden.

Wie bereits erwähnt, können Sie möglicherweise findOneAndUpdate verwenden , aber mit zusätzlichen Kosten.

function save(id, title, callback) {
    Value.findOneAndUpdate(
       {id: id, title: title}, /* query */
       {id: id, title: title}, /* update */
       { upsert: true}, /* create if it doesn't exist */
       callback);
}

Es gibt natürlich immer noch einen Rückruf, aber er schreibt die Daten erneut, wenn das Duplikat gefunden wird. Ob das ein Problem ist, hängt wirklich von den Anwendungsfällen ab.

Ich habe Ihren Code ein wenig aufgeräumt ... aber es ist wirklich ganz einfach und der Rückruf sollte klar sein. Der callback erhält die Funktion immer entweder das neu gespeicherte Dokument oder dasjenige, das als Duplikat gematcht wurde. Es liegt in der Verantwortung der Funktion, die saveNewValue aufruft um nach einem Fehler zu suchen und ihn richtig zu behandeln. Sie werden sehen, wie ich auch dafür gesorgt habe, dass der Callback unabhängig von der Art des Fehlers aufgerufen wird und immer konsistent mit dem Ergebnis aufgerufen wird.

function saveNewValue(id, title, callback) {
    if (!callback) { throw new Error("callback required"); }
    var thisValue = new models.Value({
        id:id,
        title:title //this is a unique value
    });

    thisValue.save(function(err, product) {
        if (err) {
            if (err.code === 11000) { //error for dupes
                return models.Value.findOne({title:title}, callback);
            }            
        }    
        callback(err, product);
    });
}

Alternativ können Sie das Versprechen verwenden Muster. Dieses Beispiel verwendet when.js .

var when = require('when');

function saveNewValue(id, title) {
    var deferred = when.defer();

    var thisValue = new models.Value({
        id:id,
        title:title //this is a unique value
    });

    thisValue.save(function(err, product) {
        if (err) {
            if (err.code === 11000) { //error for dupes
                return models.Value.findOne({title:title}, function(err, val) {
                    if (err) {
                        return deferred.reject(err);
                    }
                    return deferred.resolve(val);
                });
            }
            return deferred.reject(err);
        }
        return deferred.resolve(product);
    });

    return deferred.promise;
}

saveNewValue('123', 'my title').then(function(doc) {
    // success
}, function(err) {
    // failure
});