Preview:
Creating, Reading, Updating and Deleting Documents
In the last lesson, we created a model which allows us to interact with our collection of documents. The user and card models allow you to manage the user and card collections respectively.

You can perform the following actions with the model:

Create: create()
Read: findById(), findOne(), find()
Update: findByIdAndUpdate(), findOneAndUpdate(), updateOne(), updateMany()
Delete: findByIdAndRemove(), findOneAndRemove(), delete(), deleteMany()
These four actions are abbreviated as CRUD, which represents a common set of tasks when dealing with data. Let's explore the most popular methods for each of them.

Creating Documents (C)
Documents can be created via the create() method. It accepts objects with data as input and records them to the database:

// routes/users.js

/*
    code for creating routers, etc.
*/

// import the model
const User = require('../models/user');

router.post('/', (req, res) => {
  const { name, about } = req.body; // get the name and description of the user

  User.create({ name, about }); // create a document based on the input data 
});
 Save
The create() method is like a promise in that you can add then() and catch() handlers to it. This is usually done to return the data or an error to the user:

// routes/users.js

/*
    code for creating routers, etc.
*/

const User = require('../models/user');

router.post('/', (req, res) => {
  const { name, about } = req.body;

  User.create({ name, about })
    // returns the recorded data
    .then(user => res.send({ data: user }))
    // data not recorded, prompting an error
    .catch(err => res.status(500).send({ message: 'Error' }));
});
 Save
Reading Documents (R)
This involves searching for documents and reading data from them if found. There are many ways to find a document, the three most popular being findById(), findOne() and find().

Searching for a specific document: The findById() method uses the identifier to do this, i.e. the _id property that is assigned to each document in MongoDB. To find a specific document, pass the findById() identifier to the method in the form of a string:
// routes/users.js

/*
    code for creating routers, etc.
*/

const User = require('../models/user');

router.get('/:id', (req, res) => {
    User.findById(req.params.id)
        .then(user => res.send({ data: user }))
        .catch(err => res.status(500).send({ message: 'Error' }));
});
 Save
Searching for one document by specific parameters: The findOne() method returns the first document that matches the request parameters:
// find the first match with a field that equals "Elise Taylor"
User.findOne({ name: 'Elise Taylor' });
 Save
Searching all documents by specific parameters: The find() method works the same way as the findOne() method, except that it returns all documents that match the request parameters:
// find all 30-year-old users
User.find({ age: 30 });

// find all users
User.find({});
 Save
Updating Documents (U)
This is similar to reading but includes an extra step. When we update documents, first we find an entry, then we change its properties.

You can use the findByIdAndUpdate() method to update a specific document. It accepts an identifier in string form as the first argument. The second argument is an object with the properties that need to be updated:

  // routes/users.js

  // ...

  const User = require('../models/user');

  router.patch('/:id', (req, res) => {
    // updating the name of the user found by _id
    User.findByIdAndUpdate(req.params.id, { name: 'Henry George' })
      .then(user => res.send({ data: user }))
      .catch(err => res.status(500).send({ message: 'Error' }));
  });
  
 Save
You can also find the first match for the request and update it. This is done using the  findOneAndUpdate() method, which accepts two objects as arguments. The first argument is the object we're looking for, and the second argument is the updated object:

  // find the first match with the name field that equals to "Sam Taylor" and replace is with "Henry George"
  User.findOneAndUpdate({ name: 'Sam Taylor' }, { name: 'Henry George' }));
  
 Save
You can also turn every 'Sam Taylor' into 'Henry George' using the updateMany() method:

  // find all matches with the name field that equals to "Sam Taylor" and replace it with "Henry George"
  User.updateMany({ name: 'Sam Taylor' }, { name: 'Henry George' });
  
 Save
These update methods come with a caveat. By default, the parameter that the handler receives as input is the original document before the update:

User.findByIdAndUpdate(req.params.id, { name: 'Henry George' })
  // user here means the document before the update
  .then(user => res.send({ data: user }));
 Save
Fortunately, there's a way to change this. All these methods can take a third argument, which is an options object. We are interested in these three options:

Option	Description	Default Value
new	pass the updated object as input to the then() handler	false
runValidators	validate the new data before recording it into the database	false
upsert	if the document wasn't found, create it	false
Thanks to the options object, we can transfer an updated record to the then() handler. We can also set up validation or create a document if it was not found:

User.findByIdAndUpdate(
    req.params.id,
    { name: 'Henry George' },
    // pass the options object:
    {
        new: true, // the then handler receives the updated entry as input
        runValidators: true, // the data will be validated before the update 
        upsert: true // if the user entry wasn't found, it will be created
    }
)
  .then(user => res.send({ data: user }))
  .catch(user => res.send({ 'Data validation failed or another error occured.' }));
 Save
Deleting Documents (D)
Deleting a specific document: You can do this by using the findByIdAndRemove() method:
// routes/users.js

// ...

const User = require('../models/user');

router.delete('/:id', (req, res) => {
    User.findByIdAndRemove(req.params.id)
        .then(user => res.send({ data: user }))
        .catch(err => res.status(500).send({ message: 'Error' }));
});
 Save
Deleting the first match: Use findOneAndRemove():
// delete a user with a specific name
User.findOneAndRemove({ name: 'Sam Taylor' });
 Save
Delete all matches: To do this, call deleteMany():
// delete all 30-year-old users
User.deleteMany({ age: 30 });
 Save
Links
We've listed the most popular methods in this lesson, but there are many others available for working with mongoose models. You can find them all in this guide:

https://mongoosejs.com/docs/api/model.html
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter