Mongoose Schema Types, Validation & Queries Tutorial with Examples

By Digamber Rawat Last updated on
In this MongoDB tutorial, we are going to understand how to work with Mongoose schema types. How to define Schema Types efficiently Furthermore, we’ll learn to apply the custom validation in MongoDB data by defining the validation in Mongoose Schema Types using built-in Mongoose validators.We will also have a look at some basic Mongoose queries like: create, find, findById, findOne, updateOne, updateMany, findoneandupdate, save, deleteMany, deleteOne and learn to manage the collection and documents in Node app.

Mongoose schema types are used to define a particular data structure for a MongoDB document. Schema types are useful for managing a definition for path defaults, strings, numbers, validation, getters, setter, field selection, and general queries.

Mongoose Brief Introduction

Mongoose is an Object Data Modeling (ODM) tool for MongoDB and Node.js. Mongoose regulates association between data, provides schema validation. Mongoose helps in making the connection between an object in code and establishes those objects in MongoDB.

MongoDB Dictionary

Term Description
Database An organized collection of one or more data set.
Collection It’s a single or multiple sets of documents.
Document A structured set of documents in the form of Key/Value pair, same like JSON objects.
Schema Data structure type for String, Number, Date, Buffer, Boolean, Mixed, ObjectID, Array in a MongoDB document.
Model MongoDB constructors are fancy constructors, and it accepts a particular schema to make an instance of a MongoDB document. The model helps in retrieval and creating documents from a collection.

Set up Node app with Mongoose ODM and Express

We will set up a basic Node app to show you how to set up Mongoose Schema Types, Validation and Queries.

Execute command in terminal to create a fresh Node project from scratch:

mkdir node-app && cd node-app

Run command to generate the package.json file:

npm init

Then, install the required packages for our Node app.

npm install express mongoose --save

Make MongoDB Connection in Node App

In this step, we will create db folder and create a database.js file in the same folder to make the MongoDB connection in our Node app.

mkdir db && cd db && touch database.js

In the db/database.js file add the following code to set the MongoDB DATABASE => mongodatabase.

module.exports = {
  db: 'mongodb://localhost:27017/mongodatabase'
};

Create Server.js File

Run the below command from the project’s root folder to create server.js file, we will import express and mongoose packages along with Mongo database and some basic node server configuration.

touch server.js

Then, add the following code inside the server.js file:

const express = require('express'),
    mongoose = require('mongoose'),
    dataBaseConfig = require('./db/database');


// Connecting MongoDB with Mongoose
mongoose.Promise = global.Promise;
mongoose.connect(dataBaseConfig.db, {
    useNewUrlParser: true
}).then(() => {
        console.log('Database connected sucessfully ')
    },
    error => {
        console.log('Could not connected to database : ' + error)
    }
)

// Express settings
const app = express();

// Express Error Handling
app.get('*', (req, res, next) => {
    setImmediate(() => {
        next(new Error('Something went wrong'));
    });
});

app.use((error, req, res, next) => {
    // Error gets here
    res.json({
        message: error.message
    });
});


// PORT Set up
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {
    console.log('Connected to port ' + port)
})

Above code will take care of the following things:

  • Established MongoDB database connection with the help of Mongoose.
  • Implemented basic error handling with Express.
  • Set up the Express PORT with 4000

In the next step, start the MongoDB by typing the given below command in the terminal:

mongod

Open another terminal and, run the following command to start the Express server:

node server
# Connected to port 4000

Define Mongoose Schema Types and Model

In Mongoose Model and Schema are related to each other, and there is a technical difference between both the terms. Mongoose Schema is related to the structure of the document whereas Mongoose Model is accountable for retrieving and reading the documents from MongoDB database.

Let us understand Mongoose Schema Types in a simple term.

Every Schema Types in Mongoose refers to a Collection and organizes the structure of a document. It supports data validation, queries, field selection etc. Following are the valid Schema Types supported by Mongoose:

  • String
  • Number
  • Date
  • Buffer
  • Boolean
  • Mixed
  • ObjectID
  • Array

Enter the following command to define model folder and schema file in our Node project:

mkdir model && cd model && touch user.js

Then, In the user.js file we will define the valid Schema Types and create a model for user scehma.

Require Mongoose

To create schema call the Mongoose ODM at the top of the user.js file:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

Define Mongoose Schema Types

As you can see in the below example, we defined Schema Types for almost every possible data types for userSchema. The first property we declared the _id for the user schema and mapped it to Mongoose ObjectId schema type, it is also known as the primary key in MongoDB.

We’ve defined the mongoose number, buffer(file uploading), boolean (true/false), array, date schema types in our example. We also created a users collection for MongoDB, which we can check out in MongoDB database.

// Define Schema Types
let userSchema = new Schema({
    _id: new Schema.Types.ObjectId,
    name: {
        firstName: String,
        lastName: String
    },
    email: {
        type: String
    },
    mobile: {
        type: Number
    },
    avatar: {
        type: Buffer
    },
    isAccountVerified: {
        type: Boolean
    },
    socialProfiles: [{
            twitter: String
        },
        {
            facebook: String
        },
        {
            linkedin: String
        },
        {
            instagram: String
        }
    ],
    accountCreated: {
        type: Date,
        default: Date.now
    }
}, {
    // Define MongoDB Collection
    collection: 'users'
})

Create Mongoose Model

Now, we’ve successfully created the user Schema we are going to create the Mongoose Model from the userSchema.

// Define Mongoose Model
const User = mongoose.model('User', userSchema);

Using Mongoose Save Method

We’ve seen how model is created and connected to Mongoose schema. In the next step we will understand how to save data in MongoDB by using Mongoose save method using User model and userSchema type.

let John = new User({
    _id: new mongoose.Types.ObjectId(),
    name: {
        firstName: 'John',
        lastName: 'Doe'
    },
    email: 'johndoe@gmail.com',
    mobile: 01202902920,
    isAccountVerified: true,
    socialProfiles: [{
            twitter: 'https://twitter.com/johndoe'
        },
        {
            facebook: 'https://facebook.com/johndoe'
        },
        {
            linkedin: 'https://linkedin.com/johndoe'
        },
        {
            instagram: 'https://instagram.com/johndoe'
        }
    ]
})


// Save user in MongoDB using Mongoose save()
John.save((error) => {
    if (error) {
        return console.log(`Something went wrong: ${error}`);
    }
    console.log('Document saved successfully!');
})

Use built-in Mongoose Schema validators

In the previous step, We saved John’s data in the MongoDB database by using the Mongoose save() method. Mongoose comes with awesome pre-built Schema validators and additional properties. In this step, we will dig deep and understand the additional features for Strings, Numbers, Date, and how to apply built-in Mongoose Schema Type validation.

String Additional Properties:

Let us have a look at some modifiers, and modifiers help in changing the value before saving it to the database.

Property Description
lowercase Boolean, convert a string value to lowercase before storing to the database.
uppercase Boolean, convert a string value to uppercase before storing to the database.
trim Boolean, whether to always call .trim() on the value.

What are Validators?

Validators validate the value before storing it to the database.

Property Description
match RegExp, It creates a validator which examines if the given value matches with the expression.
enum Array, It establishes a validator which tests if the provided value exists in the array.
minlength Number, It creates a validator which examines if the value length is not less than the provided number.
maxlength Number, It establishes a validator which examines if the value length is not more than the provided number.

Let us see how to apply validators in Mongoose schema types.

let userSchema = new Schema({
    name: {
        type: String,
        required: true,
        lowercase: true,
        trim: true,
        minLength: 4,
        maxLength: 15
    }
});

Number Schema Types Properties:

Property Description
min Number, It builds a validator which helps in examining whether the value is greater than or equal to the provided minimum.
max Number, It builds a validator which helps in examining whether the value is less than or equal to the provided maximum.

Let us apply validators in Number property.

let userSchema = new Schema({
    mobileNumber: {
        type: Number,
        min: 9,
        max: 10
    }
});

Use Built-in Mongoose Validation in Schema Types

Mongoose provides powerful pre-built validators that we have already discussed in the previous step. In the next step, we will learn to apply the validation in Mongoose SchemaType.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

let userSchema = new Schema({
    _id: new Schema.Types.ObjectId,
    name: {
        type: String,
        required: true,
        lowercase: true,
        trim: true,
        minLength: [4, 'Name is too short!'],
        maxLength: 15
    },
    email: {
        type: String,
        required: true,
        lowercase: true
    },
    mobile: {
        type: Number,
        required: [true, 'What is your contact number?']
    },
    avatar: {
        type: Buffer,
        required: [true, 'Show us your face']
    }
}, {
    collection: 'users'
})

const User = mongoose.model('User', userSchema);

module.exports = User;

We validated Schema types using built-in validators, as you can see, we can also pass the alert messages if the validation is failed. As per the name example, we set the minLength to 4, if the length is less than the required numbers than the alert message will be displayed to the user.

Run Mongoose Queries

Mongoose provides tons of built-in helper method to find, create, read, update, delete, search data from the MongoDB database. In this final step, we are going to use some of the Mongoose helper methods to run queries on the MongoDB database to manipulate the documents and collection.

We will create a User model to run Mongoose queries.

const User = mongoose.model('User', userSchema);

CREATE Document using Mongoose Save Method

Model.save() => Method for saving single or multiple documents to the MongoDB database.

User.create({
    name: 'Iron Man'
}, (error, Iron) => {
    if (error) {
        return console.log(error);
    }
    console.log(Iron);
});

READ Document using Mongoose find, findById and findOne Methods

Model.findById() => Hepls in searching a particular document by its unique id.

User.findById(id, (error, user) => {
    // Code goes here
});

Model.findOne() => This method also helps in finding the document for the matched query.

User.findOne(id, (error, user) => {
    // Code goes here
});

Model.find() => This method searches all the document for matched query.

User.find({
    name: 'Iron Man',
    email: 'ironman@mcu.com'
}, (error, data) => {
    if (error) {
        return console.log('Something went wrong');
    }
    console.log(data);
})

UPDATE Document using Mongoose updateMany and updateOne Methods

Model.updateMany() => This method updates all the documents for matched data in the collection.

User.updateMany({
    name: 'Iron Man'
}, {
    name: 'Thor'
}, (error) => {
    // Error goes here
});

Model.updateOne() => This method updates only the first documents for matched data in the collection.

User.updateOne({
    name: 'Iron Man'
}, {
    name: 'Thor'
}, (error) => {
    // Error goes here
});

DELETE Document using Mongoose deleteOne and deleteMany Methods

Model.deleteOne() => This method deletes the first document for the matched query from the collection.

User.deleteOne({
    name: 'Iron Man'
}, {
    name: 'Thor'
}, (err) => {
    // Error goes here
});

Model.deleteMany() => This method deletes all the documents for the matched data from the collection.

User.deleteMany({
    name: 'Iron Man'
}, {
    name: 'Thor'
}, (err) => {
    // Error goes here
});

Conclusion

Finally, we have completed Mongoose Schema Types, Validation and Queries tutorial with examples. I hope you enjoyed this tutorial, and I tried my best to clear the core concepts of Mongoose. Your feedback will be highly appreciated. If you liked this tutorial, then please share it with others. And if you love to go one step further than don’t forget to check out this tutorial:- Build Angular 8 MEAN Stack CRUD App with Angular Material

Digamber Rawat
Digamber Rawat

Full stack developer with a passion for UI/UX design. I create beautiful and useful digital products to solve people’s problem and make their life easy.