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

mangusta:rileva se il documento inserito è un duplicato e, in tal caso, restituisce il documento esistente

Sebbene il tuo codice non gestisca alcuni casi di errore e utilizzi il find errato funzione, il flusso generale è tipico dando il lavoro che vuoi fare.

  1. Se sono presenti errori diversi dal duplicato, il callback non viene chiamato, il che probabilmente causerà problemi a valle nell'applicazione NodeJs
  2. usa findOne invece di find poiché ci sarà un solo risultato dato che la chiave è unica. In caso contrario, restituirà un array.
  3. Se la tua richiamata prevedeva il tradizionale error come primo argomento, puoi passare direttamente la callback a findOne funzione piuttosto che introdurre una funzione anonima.
  4. Potresti anche dare un'occhiata a findOneAndUpdate alla fine, a seconda di quale sarà lo schema e la logica finali.

Come accennato, potresti essere in grado di utilizzare findOneAndUpdate , ma con un costo aggiuntivo.

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

C'è ancora una richiamata ovviamente, ma scriverà di nuovo i dati se viene trovato il duplicato. Il fatto che si tratti di un problema dipende davvero dai casi d'uso.

Ho fatto una piccola pulizia del tuo codice... ma è davvero abbastanza semplice e il callback dovrebbe essere chiaro. Il callback alla funzione riceve sempre o il documento appena salvato o quello che è stato abbinato come duplicato. È responsabilità della funzione che chiama saveNewValue per verificare la presenza di un errore e gestirlo correttamente. Vedrai come ho anche assicurato che il callback venga chiamato indipendentemente dal tipo di errore e venga sempre chiamato con il risultato in modo coerente.

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

In alternativa, puoi utilizzare promise modello. Questo esempio utilizza 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
});