Assume we have the following collection, which I have few questions about:
{
"_id" : ObjectId("4faaba123412d654fe83hg876"),
"user_id" : 123456,
"total" : 100,
"items" : [
{
"item_name" : "my_item_one",
"price" : 20
},
{
"item_name" : "my_item_two",
"price" : 50
},
{
"item_name" : "my_item_three",
"price" : 30
}
]
}
In this case, I have to update item_name OR price at once or maybe Both at the same time.
For Example: If I provide item_name in req.body so it should only update item_name and price remain the same but if I provide price then it should do vice versa.
Basically, I mean to say it should only update that field which is provided in req.body.
I tried this
const result = await User.updateOne(
{
user_id: 123456,
'items.item_name': 'my_item_two',
},
{ $set: { items: req.body } }
)
But this is doing the same thing as I wanted but it is removing the remaining fields which are already there!
CodePudding user response:
I think you can create the $set
object in JS and then pass it to the query like this:
// body is to mock req.body
const body_1 = {
item_name: "new_name",
price: 1
}
const body_2 = {
item_name: "new_name_2"
}
const body_3 = {
price: 2
}
const getSetObject = (body) => {
update = {
$set: {}
}
Object.keys(body).forEach(k => {
update.$set[`items.$.${k}`] = body[k]
})
return update
}
console.log(getSetObject(body_1))
console.log(getSetObject(body_2))
console.log(getSetObject(body_3))
Note how this create the objects used in these queries:
So you can create the query:
const result = await User.updateOne(
{
user_id: 123456,
'items.item_name': 'my_item_two',
},
setObj
)