Mongoose upsert does not create default schema property

Example document Scheme:

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 use a common query handler to edit and create 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, the created , modified properties are not saved with the default values ​​of Date.now . Now I can call Company.create depending on the availability of the identifier, but I wonder why upsert does not use the default values ​​if the property does not exist in the new document?

I am using Mongoose version ~ 3.8.10,

+7
mongodb mongoose
source share
2 answers

What happens is that when you call a family of β€œupdate” methods, such as findByIdAndUpdate , no validation, middleware, or default values ​​are used for Mongoose. They are called only by save or create .

The reason for this is that update calls are efficient end-to-end pass-throughs for the native driver, and Mongoose only provides type-casting of fields based on a schema definition.

Mongoose 4.0 Update

Mongoose now supports setting defaults when a new document is created during update , findOneAndUpdate or findByIdAndUpdate upsert. Set setDefaultsOnInsert to true to enable this. This uses the $setOnInsert to create the default values ​​for insertion.

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

You can use { "$setOnInsert": { value: 31 } } Doc

Link: https://groups.google.com/forum/#!topic/mongoose-orm/WuJSqxPX8T8

: findOneAndUpdate([query], [doc], [options], [callback]) Doc

Example:

 model.findOneAndUpdate( { username: 'john' }, { "$setOnInsert": { points: '0' }, $push: { "boards": { "account":req.body.account, "game":req.body.game } } { upsert: true}, function(err, doc) { }); 
+7
source share

All Articles