Upserting Documents with Mongoose

May 20, 2019

In MongoDB, an upsert means an update that inserts a new document if no document matches the filter. To upsert a document in Mongoose, you should set the upsert option to the Model.updateOne() function:

const res = await Character.updateOne(
  { name: 'Jean-Luc Picard' },
  { $set: { age: 59 } },
  { upsert: true } // Make this update into an upsert
);

// Will be 1 if MongoDB modified an existing document, or 0
// if MongoDB inserted a new document.
res.nModified;
// Contains an array of descriptions of the documents inserted,
// including the `_id` of all inserted docs.
res.upserted;

To get the upserted document, you should use the Model.findOneAndUpdate() function instead of Model.updateOne().

const doc = await Character.findOneAndUpdate(
  { name: 'Jean-Luc Picard' },
  { $set: { age: 59 } },
  { upsert: true, new: true }
);

doc.name; // 'Jean-Luc Picard'
doc.age; // 59

Mongoose will insert at most one document. Even if you use Model.updateMany() with upsert, Mongoose will insert at most one document. To upsert multiple documents in bulk, you should use the Model.bulkWrite() function.

const res = await Character.bulkWrite([
  {
    updateOne: {
      filter: { name: 'Will Riker' },
      update: { age: 29 },
      upsert: true
    }
  },
  {
    updateOne: {
      filter: { name: 'Geordi La Forge' },
      update: { age: 29 },
      upsert: true
    }
  }
]);

// Contains the number of documents that were inserted because
// of an upsert
res.upsertedCount;
// Contains the number of existing documents that were updated.
res.modifiedCount;

More Mongoose Tutorials