Mongoose created a new single sub-document feature (documentation and feature request) in version 4.2.7 allowing for a single embedded sub document schema which behaves they way one-to-many sub documents behave.
What is the best way to create a default single sub-doc upon parent save?
var UserPermisssionsSchema = new mongoose.Schema({ siteAdmin: { type: Boolean, default: false, } }); var UserSchema = mongoose.Schema({ fname: String, lname: String, permissions: UserPermisssionsSchema });
I would like the permissions
field to be created with default values when the parent user document is created.
This does not work:
var UserSchema = mongoose.Schema({ fname: String, lname: String, permissions: { type: UserPermisssionsSchema , default: UserPermisssionsSchema } });
As mentioned by user whoami, mongoose only sets defaults on insert. If you are using mongoose 4. x and up and MongoDB 2.4. 0 and up you can opt-in to setting default values on update too.
In Mongoose, subdocuments are documents that are nested in other documents. You can spot a subdocument when a schema is nested in another schema. Note: MongoDB calls subdocuments embedded documents.
The versionKey is a property set on each document when first created by Mongoose. This keys value contains the internal revision of the document. The name of this document property is configurable.
A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
Please try this one
var PerSchema = new mongoose.Schema({ siteAdmin: {type: Boolean, default: false} }); var UserSchema = mongoose.Schema({ fname: String, lname: String, permissions: { type: PerSchema, default: () => ({}) }, });
Test it with Mongoose v4.4.3
var User = mongoose.model('User', UserSchema); function setUser() { var u = new User({ fname: 'asa', lname: 'dddd' }); u.save(function(err) { if (err) console.log(err); else console.log('save user successfully'); }); }
Result is
{ "_id" : ObjectId("56c68321a548be98198ebb71"), "fname" : "asa", "lname" : "dddd", "permissions" : { "_id" : ObjectId("56c68321a548be98198ebb70"), "siteAdmin" : false }, "__v" : 0 }
If you want the default value of permissions
is {}
. Please try it as below
var PerSchema = mongoose.Schema({ siteAdmin: {type: Boolean} }, {_id: false}); var UserSchema = mongoose.Schema({ fname: String, lname: String, permissions: { type: PerSchema, required: true, default: {} }, });
Test
function setUser() { var u = new User({ fname: 'asa', lname: 'dddd' }); u.save(function(err) { if (err) console.log(err); else console.log('save user successfully'); }); }
Result is
{ "_id" : ObjectId("56c687427191d54021875fb1"), "fname" : "asa", "lname" : "dddd", "permissions" : { }, "__v" : 0 }
Mongoose maintainer here, I'd recommend this:
var UserSchema = mongoose.Schema({ fname: String, lname: String, permissions: type: UserPermisssionsSchema , default: () => ({}), } });
This will make permissions
default to an empty object, with respect to any defaults the UserPermissionsSchema
might have. If you set default
to UserPermisssionsSchema
you might get some bad behavior if one of your properties happens to overlap with a mongoose schema method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With