Mongoose – Define a Model
To define a model, derive a custom schema from Mongoose’s Schema and compile the schema to a model.
In Mongoose, a schema describes the shape of documents, while a model gives you a constructor and database interface for a MongoDB collection. After you define a model, you can create documents, save them, query them, update them, and delete them through that model.
For reference, see the official Mongoose models documentation and the Mongoose Model API.
How to recognize a Mongoose Model in a Node.js application
Let us consider that we are operating a bookstore and we need to develop a Node.js Application for maintaining the book store. Also we chose MongoDB as the database for storing data regarding books. The simplest item of transaction here is a book. Hence, we shall define a model called Book and transact objects of Book Model between Node.js and MongoDB. Mongoose helps us to abstract at Book level, during transactions with the database.
In this example, Book is the model name, and documents created from this model represent individual books. A book document may have fields such as name, price, and quantity. The model becomes the main object you use in application code when working with the books collection.
Mongoose Schema versus Model
A schema and a model are related, but they are not the same thing. The schema defines the document structure. The model is compiled from the schema and is used to work with the corresponding MongoDB collection.
| Mongoose concept | Purpose | Bookstore example |
|---|---|---|
| Schema | Defines fields, data types, defaults, and validation rules. | BookSchema defines name, price, and quantity. |
| Model | Provides methods to create, query, update, and delete documents. | Book is used to create and query book documents. |
| Document | Represents one record created from a model. | book1 is one book document. |
Derive a custom Mongoose Schema for the Book model
Following is an example where we derive a custom Schema from Mongoose’s Schema.
var BookSchema = mongoose.Schema({
name: String,
price: Number,
quantity: Number
});
The schema above tells Mongoose that each book document can contain a string value for name, and number values for price and quantity. This is the basic form of a schema definition.
For stricter data handling, you can define field options such as required, default, min, and trim.
const mongoose = require('mongoose');
const BookSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
price: {
type: Number,
required: true,
min: 0
},
quantity: {
type: Number,
default: 0,
min: 0
}
});
This version is more useful in real applications because it prevents missing book names, avoids negative prices, and gives quantity a default value when it is not provided.
Compile Schema to Model in Mongoose
Once we derive a custom schema, we could compile it to a model.
Following is an example where we define a model named Book with the help of BookSchema.
var Book = mongoose.model('Book', BookSchema, <collection_name>);
<collection_name> is the name of the collection you want the documents go to.
The third argument is optional. If you omit it, Mongoose uses the model name to determine the collection name. If you want full control over the collection name, pass it explicitly.
const Book = mongoose.model('Book', BookSchema, 'books');
In this example, the Book model writes documents to the books collection. This is useful when the collection already exists or when your application must use a fixed collection name.
Initialize a Document from the Mongoose Book model
We may now use the model to initialize documents of the Model.
var book1 = new Book({ name: 'Introduction to Mongoose', price: 10, quantity: 25 });
book1 is a Document of model Book.
Creating a document object does not automatically save it to MongoDB. To store the document, call save() or use a model method such as create().
const book1 = new Book({
name: 'Introduction to Mongoose',
price: 10,
quantity: 25
});
await book1.save();
You can also create and save a document in one step with Book.create().
const book = await Book.create({
name: 'Node.js with MongoDB',
price: 15,
quantity: 10
});
Complete Mongoose model example with MongoDB connection
The following example connects to MongoDB, defines a schema, compiles the schema into a model, creates a document, and closes the connection.
const mongoose = require('mongoose');
async function main() {
await mongoose.connect('mongodb://127.0.0.1:27017/bookstore');
const BookSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
price: {
type: Number,
required: true,
min: 0
},
quantity: {
type: Number,
default: 0,
min: 0
}
});
const Book = mongoose.model('Book', BookSchema, 'books');
const book = await Book.create({
name: 'Introduction to Mongoose',
price: 10,
quantity: 25
});
console.log(book);
await mongoose.connection.close();
}
main().catch(function (error) {
console.error(error.message);
});
Run this file only after MongoDB is running locally. If you use MongoDB Atlas, replace the local URI with your Atlas connection string and keep credentials in environment variables.
Query documents through the Mongoose model
After a model is defined, it becomes the main object for database operations. For example, you can use find(), findOne(), and findById() on the model.
const availableBooks = await Book.find({ quantity: { $gt: 0 } });
const oneBook = await Book.findOne({ name: 'Introduction to Mongoose' });
This is the main reason for compiling a schema into a model. The schema defines how book documents should look, and the model provides the methods used to interact with those documents in MongoDB.
Organize a Mongoose model in a separate file
In small examples, the schema and model are often written in the same file as the connection code. In real Node.js applications, place each model in its own file so it can be reused by routes, services, and controllers.
models/book.js
const mongoose = require('mongoose');
const BookSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
price: {
type: Number,
required: true,
min: 0
},
quantity: {
type: Number,
default: 0,
min: 0
}
});
module.exports = mongoose.model('Book', BookSchema, 'books');
You can then import the model wherever it is needed.
app.js
const Book = require('./models/book');
async function listBooks() {
const books = await Book.find();
console.log(books);
}
Avoid redefining the same Mongoose model
Mongoose keeps a registry of compiled models. If the same model name is compiled repeatedly in the same running process, you may see an overwrite model error in some project setups. This can happen in test files, serverless functions, or development environments with hot reload.
A common defensive pattern is to reuse the existing model if it already exists.
module.exports = mongoose.models.Book || mongoose.model('Book', BookSchema, 'books');
For a simple Node.js script, the basic mongoose.model('Book', BookSchema) call is enough. Use the defensive pattern only when your runtime may load the same model file more than once.
Common mistakes while defining a Mongoose model
| Mongoose model mistake | Why it causes trouble | Better approach |
|---|---|---|
| Using a model before connecting to MongoDB | Database operations may wait, fail late, or hide connection problems. | Open the connection before running model operations. |
| Confusing schema and model | The schema only defines structure; it does not query the database by itself. | Use the compiled model for create, find, update, and delete operations. |
| Leaving the collection name unclear | The actual collection name may not be obvious to beginners. | Pass the third argument to mongoose.model() when you need a specific collection name. |
| Defining very loose schemas | Invalid or incomplete data may enter the collection. | Add required fields, defaults, and validation rules where needed. |
| Compiling the same model repeatedly | Some setups may throw an overwrite model error. | Define models once, or reuse mongoose.models.ModelName when needed. |
Mongoose model FAQ
What is a Mongoose model?
A Mongoose model is a compiled version of a schema. It provides the constructor and methods used to create, query, update, and delete documents in a MongoDB collection.
What is the difference between a Mongoose schema and a model?
A schema defines the structure and rules for documents. A model is created from the schema and is used to perform database operations on a MongoDB collection.
Does mongoose.model() create a MongoDB collection immediately?
Defining a model prepares Mongoose to work with a collection. The collection usually becomes visible in MongoDB after data is written or after the database creates it as part of an operation.
Why is the third argument used in mongoose.model()?
The third argument specifies the exact MongoDB collection name. Use it when you do not want Mongoose to infer the collection name from the model name.
Can one Mongoose schema be used for more than one model?
Yes. A schema can be compiled into more than one model if you intentionally want the same structure to be used with different model names or collections. In most applications, one schema is commonly paired with one model.
Editorial QA checklist for this Mongoose model tutorial
- The tutorial clearly explains that a Mongoose schema defines document structure, while a model performs database operations.
- The original bookstore example is preserved and expanded with practical details about the
Bookmodel. - The page shows the original schema and model code blocks unchanged, then adds current examples using validation and
async/await. - The collection name behavior of
mongoose.model()is explained, including when to use the optional third argument. - The tutorial includes practical model usage, including document creation, saving, querying, model file organization, and common model-definition mistakes.
Conclusion
In this Node.js Tutorial – Node.js Mongoose – Define a Model, we have learnt to use Schema to derive a custom schema and define a model by compiling the custom schema.
The basic flow is simple: define a schema, compile it with mongoose.model(), and use the resulting model to create and query documents. For maintainable Node.js applications, keep model files separate, add useful validation rules, and connect to MongoDB before running model operations.
TutorialKart.com