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;

Want to become your team's MongoDB expert? "Mastering Mongoose" distills 8 years of hard-earned lessons building Mongoose apps at scale into 153 pages. That means you can learn what you need to know to build production-ready full-stack apps with Node.js and MongoDB in a few days. Get your copy!

Did you find this tutorial useful? Say thanks by starring our repo on GitHub!

More Mongoose Tutorials