Schema
Schema is an object that defines the structure of documents in a MongoDB collection. It describes the shape and data types, serving as the blueprint or template for data. Using Schema, we can define precisely which fields a document should have, their data types, whether they are required, default values, and validation rules.
For example, if we have a user collection, we might define a Schema like this:
javascriptconst mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ username: { type: String, required: true }, password: { type: String, required: true }, email: { type: String, required: true }, createdAt: { type: Date, default: Date.now } });
In this example, userSchema defines that users should have username, password, email, and createdAt fields, with types String and Date, and except for createdAt which has a default value, the others are required.
Model
Model is a constructor or class compiled from Schema, whose instances represent individual documents in the database. Through Model, we can perform actual CRUD operations (Create, Read, Update, Delete) on the database.
Continuing the previous example, we would create a Model like this:
javascriptconst User = mongoose.model('User', userSchema);
Here, we create a Model named User associated with userSchema. This means we can now create new users, query users, update users, and delete users:
javascript// Create a new user const newUser = new User({ username: 'johndoe', password: '123456', email: 'johndoe@example.com' }); newUser.save((err, savedUser) => { if (err) throw err; // savedUser is the user document saved to the database }); // Query all users User.find({}, (err, users) => { if (err) throw err; // users is an array containing all user documents });
Why Both Schema and Model?
Schema and Model are separated because they serve distinct roles. Schema is responsible for defining the structure and rules of data, while Model provides an interface for interacting with the database.
Separating these two enhances Mongoose's design by making it more flexible and modular. You can define your data structure in one place (Schema), and then create one or more Model instances where needed to handle data. This separation also facilitates maintenance and scalability, as data structures may change frequently, and with separation, we can modify Schema without affecting the Model that uses it.
Additionally, Mongoose allows us to define instance methods, static methods, and virtual properties within Schema, enabling us to call these methods on Model instances, making data operations more convenient and efficient.