Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
837 views
in Technique[技术] by (71.8m points)

node.js - Mongoose upsert does not create default schema property

Example document Schema:

var CompanySchema = Schema({
    created: { type: Date, default: Date.now },
    modified: { type: Date, default: Date.now },
    address: { type: String, required:true },
    name: { type: String, required:true }
});

I'm using a common request handler for edit and create of "Company" documents:

exports.upsert = function(req, res) {
    helper.sanitizeObject(req.body);
    var company = {
        name: req.body.name,
        address: req.body.address
    };
    var id = req.body.id || new mongoose.Types.ObjectId();
    var queryOptions = {
        upsert: true
    };
    Company.findByIdAndUpdate(id, company, queryOptions).exec(function(error, result) {
        if(!error) {
            helper.respondWithData(req, res, {
                data: result.toJSON()
            });
        } else {
            helper.respondWithError(req, res, helper.getORMError(error));
        }
    });
};

But using this method, when a new document is inserted, created, modified properties are not saved with default values of Date.now. Now I can call Company.create depending on the existence of an id but I'm wondering why upsert does not use default values if a property does not exist on a new document?

I'm using Mongoose version ~3.8.10,

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What's going on is that none of Mongoose's validation, middleware, or default values are used when calling any of the "update" family of methods, like findByIdAndUpdate. They're only invoked by calls to save or create.

The reason for this is that the "update" calls are effectively pass-throughs to the native driver, with Mongoose only providing type-casting of the fields based on the schema definition.

Mongoose 4.0 Update

Mongoose now supports setting defaults when a new document is created during an update, findOneAndUpdate, or findByIdAndUpdate upsert. Set the setDefaultsOnInsert option to true to enable this. This uses the $setOnInsert operator to create the defaults on insert.

var queryOptions = {
    upsert: true,
    setDefaultsOnInsert: true
};
Company.findByIdAndUpdate(id, company, queryOptions).exec( ...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...