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
In Mongo 3.6 there is a function mergeObjects doing exactly what you need:
https://docs.mongodb.com/manual/reference/operator/aggregation/mergeObjects/
I had success doing it this way:
I have a function that handles my profile updates dynamically
Note: 'profile' is specific to my implementation, it is just the string of the key that you would like to modify.
Yeah, the best way is to convert the object notation to a flat key-value string representation, as mentioned in this comment: https://stackoverflow.com/a/39357531/2529199
I wanted to highlight an alternative method using this NPM library: https://www.npmjs.com/package/dot-object which lets you manipulate different objects using dot notation.
I used this pattern to programatically create a nested object property when accepting the key-value as a function variable, as follows:
This pattern lets me use nested as well as single-level properties interchangeably, and insert them cleanly into Mongo.
If you need to play around with JS Objects beyond just Mongo, especially on the client-side but have consistency when working with Mongo, this library gives you more options than the earlier mentioned
mongo-dot-notation
NPM module.P.S I originally wanted to just mention this as a comment but apparently my S/O rep isn't high enough to post a comment. So, not trying to muscle in on SzybkiSasza's comment, just wanted to highlight providing an alternative module.
If you have multiple fields to be updated
Mongo lets you update nested documents using a
.
convention. Take a look: Updating nested documents in mongodb. Here's another question from the past about a merge update, like the one you're looking for I believe: MongoDB atomic update via 'merge' documentYou can use dot-notation to access and set fields deep inside objects, without affecting the other properties of those objects.
Given the object you specified above:
We can update just
some_key.param2
andsome_key.param3
:You can delve as deep as you like. This is also useful for adding new properties to an object without affecting the existing ones.