Skip to main content

Document models

What is a model?

Collections in Mongo are equivalent to tables in relational databases. They can hold multiple JSON documents.

Documents are equivalent to records or rows of data in SQL. While an SQL row can reference data in other tables, Mongo documents usually combine that in a document.

SQL defines a schema via the table definition.

A Mongoose schema is a document data structure that is defined in the application.

Models are constructors that take a schema and create an instance of a document equivalent to records in a relational database.

In Mongo, we have a ..

  • database, which can contain one or more
  • collections which can contain one or multiple
  • documents - a item in our example
info

For Mongoose, we think in schema and models where each schema is the blueprint of the document that we want to store.

With Mongoose, we define what our data model (schema) is and construct the schema with a model. Models are constructors compiled from Schema definitions. An instance of a model is called a document. Models are responsible for creating and reading documents from the underlying MongoDB database.

Compiling a model

We create a models folder for all our models. Then we'll add a file in the models folder for each model. For example, models/itemSchema.ts

import mongoose, { Schema, Model } from "mongoose";

export type ItemType = {
owner: string;
title: string;
description?: string;
url?: string;
};

export type ItemDoc = mongoose.HydratedDocument<ItemType>;

const itemSchema = new Schema<ItemType>(
{
owner: { type: String, required: true },
title: { type: String, required: true },
description: String,
url: String,
},
{ timestamps: true }
);

export const Item: Model<ItemType> =
(mongoose.models.Item as Model<ItemType>) ||
mongoose.model<ItemType>("Item", itemSchema);

export default Item;

  • HydratedDocument is a Mongoose utility type that takes your plain ItemType and adds all the Mongoose document instance methods and properties — such as:

    • .save()

    • .validate()

    • ._id

  • The ? means the field is optional (url can be missing in item documents).

  • Creating the schema, itemSchema, defines how documents are stored in the database.

  • owner and title are required strings.

Before saving to the database, Mongoose automatically checks that required fields and data types are valid — reducing runtime errors and bad data.

If you try to save an Item without an owner, Mongoose throws a validation error before sending anything to MongoDB.

Mongoose offers a convenient, chainable syntax for db queries. Here's an example that queries the items owned by David and sorts them.

const results = await Item.find({ owner: "David" }).sort({ title: 1 });

When you call mongoose.model() on a schema, Mongoose compiles a model for you.