Sling Academy
Home/Node.js/Mongoose: How to compile a model from a schema

Mongoose: How to compile a model from a schema

Last updated: December 30, 2023

Overview

Welcome to this in-depth guide about creating models in Mongoose from schemas. Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js. It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB.

This guide will cover the essential steps and best practices for defining schemas and creating models from those schemas using Mongoose. By the end, you’ll be familiar with basic to advanced approaches for leveraging Mongoose models to interact with MongoDB efficiently in a Node.js environment.

Setting up Mongoose

Before diving into models, ensure you have Mongoose installed. If not, you can add it to your project using npm or yarn:

npm install mongoose

Or

yarn add mongoose

After installation, you can connect to your MongoDB database:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/yourdb', {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

Defining a Schema

The first step in creating a model is to define a schema. A schema is a blueprint for what kind of data can be stored in a document in MongoDB, including types of data, default values, and validation. Here’s a simple example:

const { Schema } = mongoose;

const blogSchema = new Schema({
  title: String,
  author: String,
  body: String,
  comments: [{ body: String, date: Date }],
  date: { type: Date, default: Date.now },
  hidden: Boolean,
  meta: {
    votes: Number,
    favs: Number
  }
});

Creating a Model

A Mongoose model is a wrapper for the schema and provides an interface for querying, updating, deleting and more in the database. Here’s how to create a model from a schema:

const mongoose = require('mongoose');
const { Schema } = mongoose;

const blogSchema = new Schema({
  // schema fields
});

const Blog = mongoose.model('Blog', blogSchema);

We have now defined a Blog model using our blogSchema. This model is what we’ll use to make queries to our MongoDB database.

Advanced Schema Types

Mongoose schemas can define different types and functionality such as required fields, default values, custom validation, getters and setters, field aliases, and more:

const personSchema = new Schema({
  name: {
    first: String,
    last: String
  },
  age: { type: Number, min: 0 },
  email: {
    type: String,
    required: true,
    lowercase: true,
    trim: true
  },
  createdAt: { type: Date, immutable: true, default: () => Date.now() },
  updatedAt: { type: Date, default: () => Date.now() }
});

personSchema.pre('save', function(next) {
  this.updatedAt = Date.now();
  next();
});

Using the Model

Once you have a model, you can start using it to interact with the collection that model represents. Here’s an example of creating new instance and saving it:

const Blog = mongoose.model('Blog', blogSchema);

const myBlog = new Blog({
  title: 'Mongoose Guide',
  author: 'Jane Doe',
  body: 'Models are central to Mongoose.'
});

myBlog.save()
  .then(doc => console.log('Document saved:', doc))
  .catch(err => console.error('Save error:', err));

In a real-world scenario, you would also want to handle the responses asynchronously with async/await. Here’s what that might look like:

async function createBlog(title, author, body) {
  const blog = new Blog({ title, author, body });

  try {
    const savedBlog = await blog.save();
    console.log('Document saved:', savedBlog);
  } catch (err) {
    console.error('Save error:', err);
  }
}

Interfaces and Static Methods

In addition to the default methods provided by Mongoose, you can also define your own custom document methods and static methods on schemas:

personSchema.methods.fullName = function () {
  return `${this.name.first} ${this.name.last}`;
};

personSchema.statics.findByName = function (name) {
  return this.find({ 'name.first': new RegExp(name, 'i') });
};

const Person = mongoose.model('Person', personSchema);

Now, you can do queries such as Person.findByName('John') to get all persons named John.

Conclusion

Mongoose is a powerful tool that significantly simplifies interaction with a MongoDB database. By understanding how to create models from schemas, you’re off to a strong start in structuring your data and building a robust backend API. Be sure to stay updated with the latest practices in schema definitions, validation, queries, and other essential processes within Mongoose.

Next Article: Mongoose: Defining a schema with nested objects

Previous Article: How to set up and use Mongoose with TypeScript

Series: Mongoose.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates