# Introduction to Mongoose Models

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Jan 2, 2021, updated Oct 3, 2022. Topics: Node.js, Mongoose, MongoDB.
Canonical URL: https://attacomsian.com/blog/mongoose-models

> An introduction to Mongoose models and how to use them to query, update, create, and remove documents from a MongoDB collection.

A Mongoose model is the compiled version of the [schema definition](https://attacomsian.com/blog/mongoose-schemas) that maps directly to a single document in a [MongoDB collection](https://attacomsian.com/blog/working-with-mongodb-using-mongo-shell#create-a-collection). An instance of a model is called a [document](https://attacomsian.com/blog/mongoose-documents).

Mongoose models are responsible for querying, creating, updating, and removing documents from the MongoDB database.

## Creating a model

To create a Mongoose model from a schema definition, you can use the `mongoose.model()` function:

```javascript
const mongoose = require('mongoose')
const { Schema } = mongoose

const schema = new Schema({
  title: String,
  author: String,
  price: Number
})

const Book = mongoose.model('Book', schema)
```

The first parameter is the singular name of the collection you need a model for, and the second parameter is the schema definition. Mongoose will automatically pluralize and lowercase the collection name you specified. 

For example, for the above `Book` model, the actual name of the MongoDB collection will be `books`. To retrieve all books using the [Mongo Shell](https://attacomsian.com/blog/working-with-mongodb-using-mongo-shell#list-documents), you would use the db.books.find() command.

## Creating documents

A Mongoose document is an instance of a model representing a record in a MongoDB collection. To create a new document, you can use the following code:

```javascript
const book = new Book({
  title: 'Mongoose 101',
  author: 'Atta',
  price: 9.99
})

// Save Book in MongoDB
book
  .save()
  .then(book => {
    console.log(book)
  })
  .catch(err => {
    console.log(err)
  })
```

Alternatively, you could also use the Mongoose model's `create()` function to create and save new documents:

```javascript
Book.create({
  title: 'Mongoose 101',
  author: 'Atta',
  price: 9.99
})
  .then(book => console.log(book))
  .catch(err => console.error(err))
```

## Querying documents

To query documents from a MongoDB collection, you can use the `find()` method:

```javascript
Book.find({ author: 'Atta' })
  .then(books => console.log(books))
  .catch(err => console.error(err))
```

The `find()` method returns the matching documents in the collection as an array. To find a single document, you can either use the `findById()` method or the `findOne()` method:

```javascript
// Find Single Document By ID
Book.findById('123')
  .then(book => console.log(book))
  .catch(err => console.error(err))

// Find First Matching Document
Book.findOne({ title: 'Mongoose 101' })
  .then(book => console.log(book))
  .catch(err => console.error(err))
```

## Updating documents

Just like querying, there are multiple ways available to update documents using Mongoose. Each Mongoose model has its own `update()` method for modifying documents in the collection, without returning them to the application.

Here is an example:

```javascript
Book.update({ author: 'Atta' }, { author: 'Alex' })
  .then(book => console.log(book))
  .catch(err => console.error(err))
```

The above example code updates all matching documents in the `books` collection.

If you want to update a single document in the collection and return it back to the application, use the `findOneAndUpdate()` method instead:

```javascript
Book.findOneAndUpdate(
    { title: 'Mongoose 101' }, 
    { title: 'Mongoose Basics' }, 
    { new: true })
  .then(book => console.log(book))
  .catch(err => console.error(err))
```

## Deleting documents

You can use the `findOneAndRemove()` method to delete a document from a collection. It returns the original document that was removed:

```javascript
Book.findOneAndDelete({ author: 'John' })
  .then(book => {
    console.log(book)
  })
  .catch(err => {
    console.log(err)
  })
```
