sql >> Databasteknik >  >> NoSQL >> MongoDB

mongoose:upptäck om det infogade dokumentet är en dubblett och i så fall returnera det befintliga dokumentet

Även om din kod inte hanterar några felfall och använder fel find funktion, är det allmänna flödet typiskt för det arbete du vill göra.

  1. Om det finns andra fel än dubbletten, anropas inte återuppringningen, vilket sannolikt kommer att orsaka nedströmsproblem i din NodeJs-applikation
  2. använd findOne istället för att find eftersom det bara blir ett resultat givet att nyckeln är unik. Annars kommer den att returnera en array.
  3. Om din återuppringning förväntade sig det traditionella error som det första argumentet kan du skicka återuppringningen direkt till findOne funktion snarare än att införa en anonym funktion.
  4. Du kanske också vill titta på findOneAndUpdate så småningom, beroende på vad ditt slutliga schema och logik kommer att bli.

Som nämnts kanske du kan använda findOneAndUpdate , men med extra kostnad.

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

Det finns naturligtvis fortfarande en återuppringning, men den kommer att skriva data igen om dubbletten hittas. Huruvida det är ett problem beror verkligen på användningsfall.

Jag har rensat lite i din kod... men det är egentligen ganska enkelt och återuppringningen borde vara tydlig. callback till funktionen får alltid antingen det nyligen sparade dokumentet eller det som matchades som en dubblett. Det är funktionen som anropar saveNewValues ansvar för att leta efter ett fel och hantera det korrekt. Du kommer att se hur jag också har sett till att återuppringningen anropas oavsett typ av fel och alltid anropas med resultatet på ett konsekvent sätt.

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 använda löftet mönster. Det här exemplet använder 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. MongoDB:Hur definierar man ett schema?

  2. Behöver du JPA när du använder MongoDB?

  3. Hur kontrollerar jag i Mongodb om alla dokument är unika för ett värde?

  4. Visa om listan över kapslade nycklar