Supongamos que tenemos la siguiente colección, sobre la cual tengo pocas preguntas:
{ "_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 } ] }
En este caso, tengo que actualizar item_name O precio a la vez o tal vez ambos al mismo tiempo.
Por ejemplo: si proporciono item_name en req.body, solo debería actualizar item_name y el precio sigue siendo el mismo, pero si proporciono el precio, debería hacerlo al revés.
Básicamente, quiero decir que solo debe actualizar ese campo que se proporciona en req.body.
probé esto
const result = await User.updateOne( { user_id: 123456, 'items.item_name': 'my_item_two', }, { $set: { items: req.body } } )
¡Pero esto está haciendo lo mismo que quería pero está eliminando los campos restantes que ya están allí!
Creo que puedes crear el objeto $set
en JS y luego pasarlo a la consulta de esta manera:
// 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))
Tenga en cuenta cómo esto crea los objetos utilizados en estas consultas:
Entonces puedes crear la consulta:
const result = await User.updateOne( { user_id: 123456, 'items.item_name': 'my_item_two', }, setObj )