Insert a Value at a Specific Position in an Array in MongoDB

In MongoDB, you can use the $push operator to append a value to an array.

This operator can be used with various modifiers, one of which is the $position modifier. The $position modifier allows you to specify the position within the array that you want to insert the new value.

Add Value to the Beginning of the Array

Suppose we have the following collection:

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "XL" ] }
{ "_id" : 2, "prod" : "Hat", "sizes" : [ "S", "L", "XL" ] }
{ "_id" : 3, "prod" : "Cap", "sizes" : [ "M", "L" ] }

And suppose we want to add a value to the start of the array in document 3.

We can do this:

db.products.update(
   { _id: 3 },
   { 
     $push: { 
        sizes: {
           $each: [ "S" ],
           $position: 0
        }
      } 
    }
)

Now let’s check the collection again:

db.products.find()

Result:

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "XL" ] }
{ "_id" : 2, "prod" : "Hat", "sizes" : [ "S", "L", "XL" ] }
{ "_id" : 3, "prod" : "Cap", "sizes" : [ "S", "M", "L" ] }

Arrays are zero-based, so position: 0 adds the value as the first element in the array.

Add a Value to the Middle of the Array

Suppose we want to add the value M to document 2, and we want it to go between S and L.

Here’s how we can do that:

db.products.update(
   { _id: 2 },
   { 
     $push: { 
        sizes: {
           $each: [ "M" ],
           $position: 1
        }
      } 
    }
)

Now let’s check the collection again:

db.products.find()

Result:

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "XL" ] }
{ "_id" : 2, "prod" : "Hat", "sizes" : [ "S", "M", "L", "XL" ] }
{ "_id" : 3, "prod" : "Cap", "sizes" : [ "S", "M", "L" ] }

We used $position: 1, because that’s the position we wanted M to go (i.e. the second position).

Negative Values

You can also provide a negative value as the position. When you do this, the value is inserted at the specified negative position counting back from the end.

Suppose we want to insert L in between M and XL in document 1.

Here’s how we’d go about that using a negative position:

db.products.update(
   { _id: 1 },
   { 
     $push: { 
        sizes: {
           $each: [ "L" ],
           $position: -1
        }
      } 
    }
)

Check the result:

db.products.find()

Result:

{ "_id" : 1, "prod" : "Bat", "sizes" : [ "S", "M", "L", "XL" ] }
{ "_id" : 2, "prod" : "Hat", "sizes" : [ "S", "M", "L", "XL" ] }
{ "_id" : 3, "prod" : "Cap", "sizes" : [ "S", "M", "L" ] }

With a negative index position, if you specify multiple elements in the $each array, the last added element is in the specified position from the end.