sql >> Database >  >> NoSQL >> MongoDB

mangoest:detecteer of het ingevoegde document een duplicaat is en zo ja, retourneer het bestaande document

Hoewel je code een paar foutgevallen niet afhandelt en de verkeerde find gebruikt, functie, de algemene stroom is typisch voor het werk dat u wilt doen.

  1. Als er andere fouten zijn dan het duplicaat, wordt de callback niet aangeroepen, wat waarschijnlijk downstream-problemen zal veroorzaken in uw NodeJs-toepassing
  2. gebruik findOne in plaats van find aangezien er maar één resultaat zal zijn, aangezien de sleutel uniek is. Anders wordt een array geretourneerd.
  3. Als je terugbelt de traditionele error als eerste argument zou je de callback direct kunnen doorgeven aan de findOne functie in plaats van een anonieme functie te introduceren.
  4. Misschien wil je ook kijken naar findOneAndUpdate uiteindelijk, afhankelijk van wat je uiteindelijke schema en logica zal zijn.

Zoals vermeld, kunt u mogelijk findOneAndUpdate . gebruiken , maar met extra 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);
}

Er is natuurlijk nog steeds een callback, maar het zal de gegevens opnieuw schrijven als het duplicaat wordt gevonden. Of dat een probleem is, hangt echt af van de gebruikssituaties.

Ik heb je code een beetje opgeschoond... maar het is echt heel eenvoudig en de terugroepactie zou duidelijk moeten zijn. De callback naar de functie ontvangt altijd ofwel het nieuw opgeslagen document of het document dat als een duplicaat is gekoppeld. Het is de verantwoordelijkheid van de functie die saveNewValue . aanroept om te controleren op een fout en deze correct af te handelen. Je zult zien hoe ik er ook voor heb gezorgd dat de callback wordt aangeroepen, ongeacht het type fout en altijd op een consistente manier wordt aangeroepen met het resultaat.

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

Als alternatief kunt u de belofte gebruiken patroon. Dit voorbeeld gebruikt 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. Update entiteit in redis met spring-data-redis

  2. Een ingesloten document zoeken met een specifieke eigenschap in Mongoose, Node.js, MongodDB

  3. MongoDb SafeMode vergeleken met WriteConcern

  4. Hoe flapdoodle embedded mongodb in bepaalde tests uit te schakelen?