Suppose I have a JSON Object which needs to be updated in Mongodb like
{
"_id": 12345,
"Attribute": { "Property1": "X", "Property2": true, "Property3": 123 }
}
Suppose I have a record in mongoDb
{
"_id": 12345,
"Attribute1": "abc",
"Attribute2": "xyz",
"Attribute": { "Property4": "X", "Property2": false, "Property3": 456 }
}
The resultant should update Attribute JSON while updating only the fields that are changed and keeping rest of the values intact. Resultant record in db should be like this
{
"_id": 12345,
"Attribute1": "abc",
"Attribute2": "xyz",
"Attribute": { "Property4": "X", "Property1": "X", "Property2": true, "Property3": 123 }
}
I really don't know how to achieve this in single Pass in Mongodb using JAVA spring boot. Can Anyone please help? Any help is appreciated.
CodePudding user response:
You can use Update class from org.springframework.data.mongodb.core.query package. You can write a code snippet like below.
Update updateAttribute = new Update();
updateAttribute.push("Attribute", "Your Value");
mongoOperations.updateFirst(new Query(Criteria.where("id").is(12345)), updateAttribute, "yourCollection");
Also, you need to inject constructor for MongoOperations from org.springframework.data.mongodb.core package.
CodePudding user response:
You can do it in 2 ways,
- For Mongo version 4.4 you can use pipelined updates, this allows the use of aggregation operators in the update body, specifically we'll want to use $mergeObjects, like so:
db.collection.update(
{
_id: 12345
},
[
{
$set: {
Attribute: {
$mergeObjects: [
"$Attribute",
{
"Property1": "X",
"Property2": true,
"Property3": 123
}
]
}
}
}
])
- For lesser Mongo versions you'll have to construct the update body in code, here is a javascript example ( might be slightly more annoying in spring )
const input = {
'_id': 12345,
'Attribute': { 'Property1': 'X', 'Property2': true, 'Property3': 123 },
};
const updateBody = {};
Object.keys(input.Attribute).forEach((key) => {
const updateKey = `Attribute.${key}`;
updateBody[updateKey] = input.Attribute[key];
});
db.collection.updateOne({ _id: 12345 }, { $set: updateBody });
By using the dot notation in the update body we ensure we don't overwrite existing fields in the Attribute
.