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

mongoose:Find ud af, om det indsatte dokument er en duplikat, og returner i så fald det eksisterende dokument

Mens din kode ikke håndterer nogle få fejltilfælde og bruger den forkerte find funktion, er det generelle flow typisk, hvilket giver det arbejde, du ønsker at udføre.

  1. Hvis der er andre fejl end duplikatet, kaldes tilbagekaldet ikke, hvilket sandsynligvis vil forårsage downstream-problemer i din NodeJs-applikation
  2. brug findOne i stedet for find da der kun vil være ét resultat, da nøglen er unik. Ellers returnerer den et array.
  3. Hvis dit tilbagekald forventede den traditionelle error som det første argument kunne du sende tilbagekaldet direkte til findOne funktion frem for at indføre en anonym funktion.
  4. Du vil måske også kigge på findOneAndUpdate i sidste ende, afhængigt af hvad dit endelige skema og logik vil være.

Som nævnt kan du muligvis bruge findOneAndUpdate , men med ekstra omkostninger.

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

Der er selvfølgelig stadig et tilbagekald, men det vil skrive dataene igen, hvis duplikatet er fundet. Hvorvidt det er et problem, afhænger virkelig af use cases.

Jeg har ryddet lidt op i din kode... men det er egentlig ret simpelt, og tilbagekaldet burde være klart. callback til funktionen modtager altid enten det nyligt gemte dokument eller det, der blev matchet som et dublet. Det er ansvaret for den funktion, der kalder saveNewValue at kontrollere for en fejl og håndtere den korrekt. Du vil se, hvordan jeg også har sikret mig, at tilbagekaldet kaldes uanset type fejl og altid kaldes med resultatet på en ensartet måde.

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

Alternativt kan du bruge løftet mønster. Dette eksempel bruger 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
});


  1. Sådan håndteres dato lavere end 1970 i MongoDB

  2. Skal jeg lukke forbindelsen til mongodb?

  3. Redis liste over indlejrede nøgler

  4. Redis-statistik