Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

Dot notation for objects embedded within vectors

Hi,
I was trying to understand how to update an object with an embedded object inside a vector:

Here is an example workflow, of course its contrived:

db.test.insert({“a”:1})
db.test.update({“a”:1}, {$set : {“f.a.b”:2}})

This works as expected, yielding the object:

db.test.find({“a”:1})
{ “_id” : ObjectId("…"), “a” : 1, “f” : { “a” : { “b” : 2 } } }

However, if my aim is to add a new vector containing compound objects:

db.test.update({“a”:1}, {$set : {“f”:[{“a.b”:2}]}})

I am getting:

db.test.find({“a”:1})
{ “_id” : ObjectId("…"), “a” : 1, “f” : [ { “a.b” : 2 } ] }

What I wanted to get is

{ “_id” : ObjectId("…"), “a” : 1, “f” : [{ “a” : { “b” : 2 }}]}

What is the correct way to do this?

Thanks!

Hi Shlomi,

To update a collection with array field and add elements to it you use the $push array update operator.

In the code db.test.update({“a”:1}, {$set : {“f”:[{“a.b”:2}]}}), you are trying to update the document with an array field f with one element, an object, { "a" : { "b" : 2 } }.

The correct way would be:

MY_OBJ = { "a" : { "b" : 2 } }
db.test.update( { "a": 1 }, { $push : { "f": MY_OBJ } } )

(wave) Hi @Shlomi_Vaknin and welcome to the community!

In addition to the method that @Prasad_Saya gives, you could also use the following:

> db.test.update({"a": 1}, {"$set": {"f": [{"a": {"b": 2}}]}})
{
  acknowleged: 1,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0,
  insertedId: null
}

This updates the f field as you would like as well:

> db.test.find()
[
  {
    _id: 5ee21df45b4e7466e2f4f520,
    a: 1,
    f: [ { a: { b: 2 } } ]
  }
]

Both methods work. Prasad’s method uses the $push operator to add the document to the array, where as my method has you manually build the array with the document in it.

I want to add some related information. about the update operators $set and $push.

$set sets a field’s value. If the field doesn’t exist, it creates the field and sets the value. If the field already exists, then the existing value is completely replaced by the new value.

$push adds an element to an array. If the array field already exists, the element is added to the array. If the field doesn’t exist, then a new array field is created and the element is added to the array.

So, you can choose either of the update operators, depending upon your need. I think, arrays should be worked with $push - unless you want to completely replace the existing array with a new value.

1 Like

@Prasad_Saya thanks for the clarification. Whether to use $set or $array does depend on what you are trying to accomplish, and I did indeed forget to leave that comment off my post.