Authors: @Jacqueline Osborn

Last Updated: 4/13/21

Mongoose is a package that makes it easier to define MongoDB document schemas (the shape and content of documents). Normally in MongoDB, you aren't constrained to a rigid schema - you can change around the fields as much as you want - but with Mongoose, the schema is more rigid. It will error if you try and add a document with a field that isn't in the schema, and error if you try to add a document without a field that is required. This can lead to less bugs in our code!

Schemas

A Schema in Mongoose essentially just represents the shape of the documents in a MongoDB collection. To create, say, a user Schema, you can do something like this:

const userSchema = new Schema({
	name: { type: String, required: true },
	age: Number,
	readBooks: { type: [String], default: [] },
});

Here, we have defined a schema for a user, that has fields "name", "age", and "readBooks" (an array of strings). We also specified that name has to be included - this is part of the rigidity that Mongoose places on MongoDB. If we try and create a user that does not have a name, Mongoose will throw an error. Additionally, we specified a default value for readBooks - if we did not supply a value for readBooks when creating a user, it will default to an empty array.

<aside> 💡 Note: Each Schema auto-generates an _id field that is unique per document

</aside>

There are a lot of other options you can include in a Schema, so if you require some more complicated logic, make sure to check out the documentation.

Subdocuments

We can embed documents in other documents - in Mongoose, this means embedding a Schema in another Schema. Mongoose calls these subdocuments.

Say instead of having readBooks be just an array of strings, we wanted it to be an array of books with other properties - and we also want to track a user's favoriteBook. We can do something like this:

const bookSchema = new Schema({
	name: { type: String, required: true },
	author: { type: String, required: true },
});

const userSchema = new Schema({
	name: { type: String, required: true },
	age: Number,
	readBooks: { type: [bookSchema], default: [] },
	favoriteBook: bookSchema,
});

You can see all we did was create another Schema, and put that instead of String in readBooks, as well as adding another field favoriteBook that must be in the shape of bookSchema.

Defining a Model

Models allow you to interact with MongoDB - each instance of a model is a document. You use models to create/read/update/delete data in MongoDB. Models are made from Schemas!

To define a User model, assuming we have defined the Schemas as above, we can just include this line of code:

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