Open In App

Mongoose Validation

Last Updated : 20 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Mongoose is an elegant solution for modeling and managing MongoDB data in a Node.js environment. One of its powerful features is data validation which ensures that data is correctly formatted and meets specific business rules before being saved to the database. This article explores Mongoose validation, including its types, examples, and how to effectively use it in our Node.js applications.

What is Mongoose Validation?

Mongoose validation is a middleware that runs before a document is saved to the database. It automatically validates data based on rules defined in the schema, ensuring that all fields meet the specified requirements. If the data doesn’t meet the validation criteria, an error is thrown, preventing the document from being saved.

Types of mongoose validation:

In Mongoose there are two types of validation:

  1. Built-in validation: Predefined validators provided by Mongoose, such as required, min, max, and unique.
  2. Custom validation: User-defined validation logic for more specific or complex validation rules.

To get a better understanding of how built-in validators work, let’s look at the following:

1. Built-in Validators

Mongoose provides several built-in validators that are simple to use and provide out-of-the-box validation for common data requirements.

A. Required validator

Schema uses Required Validator when it is mandatory that a field cannot be left empty when saving a document. The required validator takes an array with 2 items, first a Boolean var and a message to return the validation if it fails. If the value is missing, Mongoose will throw an error.

Syntax:

required: [true, “user name is required”]

we can also specify the Required validator without custom error message,

required: true

Example:

const personSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Name is required']
}
});

Explanation: In this example, the field name is required. If an attempt is made to save a document with a missing name, Mongoose will return the error: “Name is required.”

B. Unique validator

Unique is not a validator, but an option. If the unique option is set, Mongoose will require each document to have a unique value for each path. Unique option takes an array with 2 items, first a Boolean var and a custom error message. Although it’s not technically a validator, it is an important option for fields like email or usernames.

unique: [true, ’email already exists’]

we can also specify unique option without custom error message,

unique: true

Example:

const userSchema = new mongoose.Schema({
email: {
type: String,
unique: [true, 'Email already exists']
}
});

Explanation: The email field is unique in the database. If a document with a duplicate email is inserted, Mongoose will return an error: “Email already exists.”

C. Min and Max Validators

The min and max validators ensure that numeric or date values fall within a specified range. If the value is outside the defined bounds, an error is thrown.

Syntax

min: [value, ‘Error message’]

max: [value, ‘Error message’]

Example:

const personSchema = new mongoose.Schema({
age: {
type: Number,
required: true,
min: [18, 'Age must be 18 or above']
}
});

Explanation: In this example, the age field must be at least 18. If an age value lower than 18 is provided, Mongoose will return the error: “Age must be 18 or above”.

2. Custom validators

In addition to the built-in validators, we can define custom validators. In custom validation, a validation function is passed along with the declaration. Defining a custom validator involves creating a specialized function within the schema’s field definition to ensure that the data inserted or updated meets specific criteria beyond the standard validation rules offered by Mongoose.

Defining a Custom Validator

To define a custom validator, we need to pass a validation function to the schema definition. This function can return true for valid data or false (or an error message) for invalid data.

Syntax

validate: function(value) {

return value === ‘expected value’; // or return an error message

}

Example:

const personSchema = new mongoose.Schema({
username: {
type: String,
required: true,
validate: {
validator: function(value) {
return /^[a-zA-Z0-9]+$/.test(value); // username must contain only letters and numbers
},
message: 'Username must be alphanumeric'
}
}
});

Explanation: In this example, the username field uses a custom validator that checks if the value contains only alphanumeric characters. If the validation fails, Mongoose will return the error: “Username must be alphanumeric.”

How Does Mongoose Validation Work?

Mongoose validation occurs automatically when calling the save() method. Before saving a document, Mongoose runs all validation rules defined in the schema. If the data passes all validations, it is saved to the database. If any validation fails, Mongoose throws an error, and the document is not saved.

Example 1: Basic Validation

In this example, we will use a “required” validator to check whether a value is passed to the document or not before saving it to the DB.

// main.js

const mongoose = require('mongoose')

// Database connection
mongoose.connect('mongodb://localhost:27017/query-helpers', {
dbName: 'event_db',
useNewUrlParser: true,
useUnifiedTopology: true
}, err => err ? console.log(err) :
console.log('Connected to database'));

const personSchema = new mongoose.Schema({
name: {
type: String,
required: true
}
});

const Person = mongoose.model('Person', personSchema);
const person = new Person({});
(async () => {
try {
await person.save();
} catch (err) {
console.log(err)
}
})();

Step to Run Application: Run the application using the following command from the root directory of the project:

node main.js

Output: 

Example 2: Using “Required” and “Min” Validators for Age Validation

In this example, we will use both “required” and a “min” validator to check whether a value is passed to the document or not and whether the value is above a threshold number before saving it to the Database.

// main.js

const mongoose = require('mongoose')

// Database connection
mongoose.connect('mongodb://localhost:27017/query-helpers', {
dbName: 'event_db',
useNewUrlParser: true,
useUnifiedTopology: true
}, err => err ? console.log(err) :
console.log('Connected to database'));

const personSchema = new mongoose.Schema({
age: {
type: Number,
required: true,
min: [18, 'Age must be 18 or above']
}
});

const Person = mongoose.model('Person', personSchema);
const person = new Person({ age: 16 });
(async () => {
try {
await person.save();
} catch (err) {
console.log(err)
}
})();

Step to Run Application: Run the application using the following command from the root directory of the project:

node main.js

Output:

Conclusion

Mongoose validation provides a robust and flexible way to ensure data integrity before saving documents to MongoDB. With built-in validators and the ability to define custom validation rules, Mongoose helps maintain data consistency in our application. However, always complement Mongoose validation with additional application-level validation and data sanitization for comprehensive data protection. By understanding and implementing Mongoose validation, we can ensure that our Node.js applications handle data effectively and securely.



Next Article

Similar Reads