Documents

Mongoose documents represent a one-to-one mapping to documents as stored in MongoDB. Each document is an instance of its Model.

Retrieving

There are many ways to retrieve documents from MongoDB. We won't cover that in this section. See the chapter on querying for detail.

Updating

There are a number of ways to update documents. We'll first look at a traditional approach using findById:

Tank.findById(id, function (err, tank) {
  if (err) return handleError(err);

  tank.size = 'large';
  tank.save(function (err, updatedTank) {
    if (err) return handleError(err);
    res.send(updatedTank);
  });
});

You can also use .set() to modify documents. Under the hood, tank.size = 'large'; becomes tank.set({ size: 'large' }).

Tank.findById(id, function (err, tank) {
  if (err) return handleError(err);

  tank.set({ size: 'large' });
  tank.save(function (err, updatedTank) {
    if (err) return handleError(err);
    res.send(updatedTank);
  });
});

This approach involves first retrieving the document from Mongo, then issuing an update command (triggered by calling save). However, if we don't need the document returned in our application and merely want to update a property in the database directly, Model#update is right for us:

Tank.update({ _id: id }, { $set: { size: 'large' }}, callback);

If we do need the document returned in our application there is another, often better, option:

Tank.findByIdAndUpdate(id, { $set: { size: 'large' }}, { new: true }, function (err, tank) {
  if (err) return handleError(err);
  res.send(tank);
});

The findAndUpdate/Remove static methods all make a change to at most one document, and return it with just one call to the database. There are several variations on the findAndModify theme. Read the API docs for more detail.

Note that findAndUpdate/Remove do not execute any hooks or validation before making the change in the database. You can use the runValidators option to access a limited subset of document validation. However, if you need hooks and full document validation, first query for the document and then save() it.

Validating

Documents are validated before they are saved. Read the api docs or the validation chapter for detail.

Overwriting

You can overwrite an entire document using .set(). This is handy if you want to change what document is being saved in middleware.

Tank.findById(id, function (err, tank) {
  if (err) return handleError(err);
  // Now `otherTank` is a copy of `tank`
  otherTank.set(tank);
});

Next Up

Now that we've covered Documents, let's take a look at Sub-documents.