Given this document saved in MongoDB
{ _id : ..., some_key: { param1 : "val1", param2 : "val2", param3 : "val3" } }
An object with new information on param2
and param3
from the outside world needs to be saved
var new_info = { param2 : "val2_new", param3 : "val3_new" };
I want to merge / overlay the new fields over the existing state of the object so that param1 doesn't get removed
Doing this
db.collection.update( { _id:...} , { $set: { some_key : new_info } }
Will lead to MongoDB is doing exactly as it was asked, and sets some_key to that value. replacing the old one.
{ _id : ..., some_key: { param2 : "val2_new", param3 : "val3_new" } }
What is the way to have MongoDB update only new fields (without stating them one by one explicitly)? to get this:
{ _id : ..., some_key: { param1 : "val1", param2 : "val2_new", param3 : "val3_new" } }
I'm using the Java client, but any example will be appreciated
To update a single field or specific fields just use the $set operator. This will update a specific field of "citiName" by value "Jakarta Pusat" that defined by $set operator.
Overview. Upsert is a combination of insert and update (inSERT + UPdate = upsert). We can use the upsert with different update methods, i.e., update, findAndModify, and replaceOne. Here in MongoDB, the upsert option is a Boolean value.
I solved it with my own function. If you want to update specified field in document you need to address it clearly.
Example:
{ _id : ..., some_key: { param1 : "val1", param2 : "val2", param3 : "val3" } }
If you want to update param2 only, it's wrong to do:
db.collection.update( { _id:...} , { $set: { some_key : new_info } } //WRONG
You must use:
db.collection.update( { _id:...} , { $set: { some_key.param2 : new_info } }
So i wrote a function something like that:
function _update($id, $data, $options=array()){ $temp = array(); foreach($data as $key => $value) { $temp["some_key.".$key] = $value; } $collection->update( array('_id' => $id), array('$set' => $temp) ); } _update('1', array('param2' => 'some data'));
If I understand the question correctly, you want to update a document with the contents of another document, but only the fields that are not already present, and completely ignore the fields that are already set (even if to another value).
There is no way to do that in a single command.
You have to query the document first, figure out what you want to $set
and then update it (using the old values as a matching filter to make sure you don't get concurrent updates in between).
Another reading of your question would be that you are happy with $set
, but do not want to explicitly set all fields. How would you pass in the data then?
You know you can do the following:
db.collection.update( { _id:...} , { $set: someObjectWithNewData }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With