$setOnInsert Operator in MongoDB – Simple Guide

In this tutorial, I will explain how to use the $setOnInsert operator in MongoDB.

The $setOnInsert operator simply inserts a field on an update operation when upsert is set to true and it results in an insert of a document. if the operation does not result in an insert of a document(s), then the $setOnInsert operator does not do anything.

This guide shall take you through several examples to explain how you can use the $setOnInsert operator in MongoDB.

The $setOnInsert Operator Syntax in MongoDB

Here’s what the syntax looks like of the $setOnInsert operator in the Mongo shell:

db.collection.update(
   query,
   { $setOnInsert: { field1: value1, ... } },
   { upsert: true }
)

To insert an embedded or nested document, we can use the dot notation in MongoDB. You can use the $setOnInsert operator with the upsert option as true with different update operation functions like update(), updateMany(), and findAndModify().

Using the $setOnInsert Operator in MongoDB

Let us get started with our examples to learn to use this operator in MongoDB from the mongo shell.

Inserting a Document Using the $setOnInsert Operator in MongoDB

We now insert a regular document inside a collection.

  • Start the MongoDB local database server
  • Choose the database you want to use in the mongo shell and navigate into it using the use database_name command
  • I am using the randomCollection collection which is totally empty right now. I will first insert a document inside it although you choose not to:
> db.randomCollection.insertOne({
...         "name" : "Katherine",
...         "age" : 3,
...         "breed" : "Persian Cat",
...         "personality" : {
...                 "dogFriendly" : true,
...                 "childFriendly" : true
...         }
... })


{
        "acknowledged" : true,
        "insertedId" : ObjectId("6172f11a0bcd9f2d53f6a355")
}
  • Checking if the cat document has been added:
> db.randomCollection.find().pretty()
{
        "_id" : ObjectId("6172f11a0bcd9f2d53f6a355"),
        "name" : "Katherine",
        "age" : 3,
        "breed" : "Persian Cat",
        "personality" : {
                "dogFriendly" : true,
                "childFriendly" : true
        }
}
  • I will now query for a document that does not exist in our collection and set upsert as true. I am also using the $set operator here:
> db.randomCollection.update(
...   { name: "Bella" },
...   {
...      $set: { age: 5 },
...      $setOnInsert: { breed: "Scottish Fold Cat" }
...   },
...   { upsert: true }
... )


WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("6172f3a91a205e9b1fb741ea")
})

The operation seems successful as the WriteResult shows nUpserted as 1.

  • Let us see if our document is added:
> db.randomCollection.find().pretty()
{
        "_id" : ObjectId("6172f2fa0bcd9f2d53f6a356"),
        "name" : "Katherine",
        "age" : 3,
        "breed" : "Persian Cat",
        "personality" : {
                "dogFriendly" : true,
                "childFriendly" : true
        }
}
{
        "_id" : ObjectId("6172f3a91a205e9b1fb741ea"),
        "name" : "Bella",
        "age" : 5,
        "breed" : "Scottish Fold Cat"
}

Using $setOnInsert Operator for Embedded or Nested Documents

I am now using the $setOnInsert operator to insert embedded or nested documents in our collection.

> db.randomCollection.update(
...   { name: "Fiona" },
...   {
...      $set: { age: 8 },
...      $setOnInsert: { breed: "Siberian Cat", "personality.dogFriendly" : true }
...   },
...   { upsert: true }
... )


WriteResult({
        "nMatched" : 0,
        "nUpserted" : 1,
        "nModified" : 0,
        "_id" : ObjectId("6172f5031a205e9b1fb741f3")
})
  • Let us check how our document now looks:
> db.randomCollection.find().pretty()

{
        "_id" : ObjectId("6172f2fa0bcd9f2d53f6a356"),
        "name" : "Katherine",
        "age" : 3,
        "breed" : "Persian Cat",
        "personality" : {
                "dogFriendly" : true,
                "childFriendly" : true
        }
}
{
        "_id" : ObjectId("6172f3a91a205e9b1fb741ea"),
        "name" : "Bella",
        "age" : 5,
        "breed" : "Scottish Fold Cat"
}
{
        "_id" : ObjectId("6172f5031a205e9b1fb741f3"),
        "name" : "Fiona",
        "age" : 8,
        "breed" : "Siberian Cat",
        "personality" : {
                "dogFriendly" : true
        }
}

Using the $setOnInsert Operator on Documents that Exist in MongoDB

Let us try to use the $setOnInsert operator on a document that exists, I am not using the $set operator this time.

> db.randomCollection.update(
...   { name: "Fiona" },
...   {
...      $setOnInsert: { "personality.childFriendly" : true }
...   },
...   { upsert: true }
... )

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

The nMatched shows 1 however, the nUpserted and nModified values show 0.

  • Let us check our collection for the last time now:
> db.randomCollection.find().pretty()

{
        "_id" : ObjectId("6172f2fa0bcd9f2d53f6a356"),
        "name" : "Katherine",
        "age" : 3,
        "breed" : "Persian Cat",
        "personality" : {
                "dogFriendly" : true,
                "childFriendly" : true
        }
}
{
        "_id" : ObjectId("6172f3a91a205e9b1fb741ea"),
        "name" : "Bella",
        "age" : 5,
        "breed" : "Scottish Fold Cat"
}
{
        "_id" : ObjectId("6172f5031a205e9b1fb741f3"),
        "name" : "Fiona",
        "age" : 8,
        "breed" : "Siberian Cat",
        "personality" : {
                "dogFriendly" : true
        }
}

Read More: $nin Operator in MongoDB: Comprehensive 2021 Guide

Conclusion

In this article, we learned how to use the $setOnInsert operator in MongoDB.

Noteworthy References

MongoDB Docs

Aneesha S
Aneesha S
Articles: 171