I want to update the record of a nested document, my document looks like this:
[
{
"_id": "60753fd9b249ad0dfa1eeb48",
"name": "Random Name 1",
"email": "randomname1@zmel.kom",
"likings": [
{
"breakfast": {
"eat": "oats",
"drink": "milk"
}
},
{
"lunch": {
"eat": "beef",
"drink": "pepsi"
}
},
{
"dinner": {
"eat": "steak",
"drink": "champagne"
}
}
]
},
{
"_id": "60753fd9b249ad0dfa1eeb58",
"name": "Random Name 2",
"email": "randomname2@zmel.kom",
"likings": [
{
"breakfast": {
"eat": "cereals",
"drink": "coffee"
}
},
{
"lunch": {
"eat": "salad",
"drink": "hot-water"
}
},
{
"dinner": {
"eat": "biryani",
"drink": "apple juice"
}
}
]
}
]
Now I want to update the value of drink
for dinner
for Random Name 2
but I don't know the index of dinner, it could be above the lunch
, it could be just below the breakfast
.
Here's what I have tried in Python :
oid = data[0] # fetched from flask form
to_be_updated = data[1] # fetched from flask form
update_value = data[2] # fetched from flask form
condition = {"_id" : oid}
update_value = {
"$set" : {
f"likings.{to_be_updated}.drink" : update_value
}
}
response = mongo.db.food.update(condition, update_value)
but the error I am getting is:
pymongo.errors.WriteError: Cannot create field 'dinner' in element <complete element description>
What my other strategy that I am planning on using is, only match ID and then update likings
by keeping the values that are no needed to be changed as it is and altering that value that i want to change. But this approach seems too obvious and semantically wrong since I am using not updating but updating
kind of strategy i.e disturbing the collection schema for no actual reason. Is there a way to do that or should I just continue with what I am thinking
DEMO: MongoDB Playground
First of all, there are errors in your JSON.
[
{
"_id": "60753fd9b249ad0dfa1eeb48",
"name": "Random Name 1",
"email": "randomname1@zmel.kom",
"likings": [
{
"breakfast": {
"eat": "oats",
"drink": "milk"
}
},
{
"lunch": {
"eat": "beef",
"drink": "pepsi"
}
},
{
"dinner": {
"eat": "steak",
"drink": "champagne"
}
}
]
},
{
"_id": "60753fd9b249ad0dfa1eeb58",
"name": "Random Name 2",
"email": "randomname2@zmel.kom",
"likings": [
{
"breakfast": {
"eat": "cereals",
"drink": "coffee"
}
},
{
"lunch": {
"eat": "salad",
"drink": "hot-water"
}
},
{
"dinner": {
"eat": "biryani",
"drink": "apple juice"
}
}
]
}
]
Try this:
db.collection.update({
"name": "Random Name 2",
"likings.dinner": {
"$exists": true
}
},
{
"$set": {
"likings.$.dinner.drink": "PEPSI"
}
})
You can change dinner
to whatever field you want to update accordingly.