An Introduction to Mongoose SchemaTypes
In Mongoose, a SchemaType is a configuration object for a single path within a schema. A SchemaType says what type the path should be, how to validate that path, what the default value for the path is, and other Mongoose-specific config options.
const schema = Schema({ name: String, age: Number });
schema.path('name') instanceof mongoose.SchemaType; // true
schema.path('age') instanceof mongoose.SchemaType; // true
The SchemaType class is just a base class. There are several classes
that inherit from SchemaType that represent different core Mongoose Types:
mongoose.Schema.Types.Stringmongoose.Schema.Types.Numbermongoose.Schema.Types.Datemongoose.Schema.Types.Buffermongoose.Schema.Types.Booleanmongoose.Schema.Types.Mixedmongoose.Schema.Types.ObjectId(or, equivalently,mongoose.ObjectId)mongoose.Schema.Types.Arraymongoose.Schema.Types.Decimal128mongoose.Schema.Types.Map
For example:
const schema = Schema({ name: String, age: Number });
schema.path('name') instanceof mongoose.SchemaType; // true
schema.path('name') instanceof mongoose.Schema.Types.String; // true
schema.path('age') instanceof mongoose.SchemaType; // true
schema.path('age') instanceof mongoose.Schema.Types.Number; // true
Working With SchemaTypes
You normally don't have to work with SchemaType instances directly.
You can declare validators and defaults in your schema definition. For example, the below example sets the default age to 25
and adds a validator that ensures age is at least 21.
const schema = Schema({
age: {
type: Number,
default: 25,
validate: v => v >= 21
}
});
The above is how you normally declare defaults and validators in Mongoose.
But there's nothing stopping you from adding them on the age SchemaType
after creating your schema.
// Equivalent:
const schema = Schema({ age: Number });
schema.path('age').default(25);
schema.path('age').validate(v => v >= 21);
The latter syntax is equivalent to the former, but isn't commonly used.
The most common case for working with SchemaType instances directly
is with embedded discriminators.
For example, suppose you have an Order schema, and an Order
has an embedded list of products. Each product may be a book,
computer, or something else, and each type of product can have different properties.
Embedded discriminators let an array store subdocuments that conform
to different schemas based on each subdocument's __t property.
const productSchema = new Schema({
imageURL: String,
name: String
}, { discriminatorKey: '__t' });
const bookSchema = new Schema({
author: String
});
const computerSchema = new Schema({
ramGB: Number
});
const orderSchema = new Schema({
createdAt: Date,
product: [productSchema]
});
// Add discriminators to the `products` SchemaType.
orderSchema.path('products').discriminator('Book', bookSchema);
orderSchema.path('products').discriminator('Computer', computerSchema);
const Order = mongoose.model('Order', orderSchema);