MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

mangouste :détecte si le document inséré est un doublon et si c'est le cas, renvoie le document existant

Bien que votre code ne gère pas quelques cas d'erreur et utilise le mauvais find fonction, le flux général est typique donnant le travail que vous voulez faire.

  1. S'il y a des erreurs autres que le doublon, le rappel n'est pas appelé, ce qui entraînera probablement des problèmes en aval dans votre application NodeJs
  2. utiliser findOne plutôt que find car il n'y aura qu'un seul résultat étant donné que la clé est unique. Sinon, il renverra un tableau.
  3. Si votre rappel s'attendait à la traditionnelle error comme premier argument, vous pouvez directement passer le rappel au findOne plutôt que d'introduire une fonction anonyme.
  4. Vous pouvez également consulter findOneAndUpdate éventuellement, en fonction de votre schéma final et de votre logique.

Comme mentionné, vous pourrez peut-être utiliser findOneAndUpdate , mais avec un coût supplémentaire.

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

Il y a toujours un rappel bien sûr, mais il réécrira les données si le doublon est trouvé. Que ce soit un problème dépend vraiment des cas d'utilisation.

J'ai fait un petit nettoyage de votre code... mais c'est vraiment très simple et le rappel devrait être clair. Le callback à la fonction reçoit toujours soit le document nouvellement enregistré, soit celui qui a été identifié comme doublon. C'est la responsabilité de la fonction appelant saveNewValue pour vérifier une erreur et la traiter correctement. Vous verrez comment j'ai également fait en sorte que le rappel soit appelé quel que soit le type d'erreur et qu'il soit toujours appelé avec le résultat de manière cohérente.

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

Alternativement, vous pouvez utiliser la promesse motif. Cet exemple utilise 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
});