mongoose: detect if document inserted is a duplicate and if so, return the existing document

后端 未结 2 717
感情败类
感情败类 2021-02-13 13:47

This is my code:

    var thisValue = new models.Value({
        id:id,
        title:title //this is a unique value
    });

    console.log(thisValue);

    thi         


        
2条回答
  •  庸人自扰
    2021-02-13 14:02

    I really like WiredPrairie's answer, but his promise implementation is way too complicated.

    So, I decided to add my own promise implementation.

    Mongoose 3.8.x

    If you're using latest Mongoose 3.8.x then there is no need to use any other promise module, because since 3.8.0 model .create() method returns a promise:

    function saveNewValue(id, title) {
        return models.Value.create({
            id:id,
            title:title //this is a unique value
        }).then(null, function(err) {
            if (err.code === 11000) {
                return models.Value.findOne({title:title}).exec()
            } else {
                throw err;
            }
        });
    }
    
    saveNewValue('123', 'my title').then(function(doc) {
        // success
        console.log('success', doc);
    }, function(err) {
        // failure
        console.log('failure', err);
    });
    

    models.Value.findOne({title:title}).exec() also returns a promise, so there is no need for callbacks or any additional casting here.

    And if you don't normally use promises in your code, here is callback version of it:

    function saveNewValue(id, title, callback) {
        models.Value.create({
            id:id,
            title:title //this is a unique value
        }).then(null, function(err) {
            if (err.code === 11000) {
                return models.Value.findOne({title:title}).exec()
            } else {
                throw err;
            }
        }).onResolve(callback);
    }
    

    Previous versions of Mongoose

    If you're using any Mongoose version prior to 3.8.0, then you may need some help from when module:

    var when = require('when'),
        nodefn = require('when/node/function');
    
    function saveNewValue(id, title) {
        var thisValue = new models.Value({
            id:id,
            title:title //this is a unique value
        });
    
        var promise = nodefn.call(thisValue.save.bind(thisValue));
    
        return promise.spread(function(product, numAffected) {
            return product;
        }).otherwise(function(err) {
            if (err.code === 11000) {
                return models.Value.findOne({title:title}).exec()
            } else {
                throw err;
            }
        });
    }
    

    I'm using nodefn.call helper function to turn callback-styled .save() method into a promise. Mongoose team promised to add promises support to it in Mongoose 4.x.

    Then I'm using .spread helper method to extract the first argument from .save() callback.

提交回复
热议问题