Estoy trabajando en una API, en mi interfaz, envío una solicitud PATCH a una ruta que puede actualizar el peso, la altura o el sexo. La estructura de mi modelo de esquema es esta:
/** @format */ const mongoose = require('mongoose'); const Schema = mongoose.Schema; const userSchema = new Schema( { username: { type: String, required: true, unique: true }, password: { type: String, required: true }, email: { type: String, required: true, unique: true }, userNumber: { type: Number, required: true }, description: { type: String }, verified: { type: Boolean, default: false }, isAdmin: { type: Boolean, default: false }, isSubscriber: { type: Boolean, default: false }, isDisabled: { type: Boolean, default: false }, characteristics: { height: { type: Number, default: 0 }, weight: { type: Number, default: 0 }, gender: { type: String, default: 'other' }, }, acceptedTerms: { type: Number, required: true }, }, { timestamps: true } ); module.exports = mongoose.model('User', userSchema);Ahora las acciones de mi controlador son bastante similares para encontrar la actualización de esos 3 valores:
exports.changeSex = async (req, res, next) => { // Requirements const userId = req.params.userId; const newGender = req.body.gender; console.log('userId: ' + userId); console.log('newGender: ' + req.body.gender); try { const user = await User.findOneAndUpdate( { _id: userId }, { characteristics: { gender: newGender } } ); console.log('User successfully updated.'); return res.status(200).json({ success: true, gender: newGender }); } catch (err) { console.log('ERROR: ', err); return res.status(400).json({ success: false, error: err }); } };El problema al que me enfrento es que cada vez que ejecuto una de estas 3 acciones, una reemplaza a las otras.
Por ejemplo, cambiar el género generará altura: 0 y peso: 0, y si actualizo el peso: 10, el género vuelve a ser género: 'otro'.
Parece que findAndUpdateOne reemplaza todo usando los valores predeterminados de mi esquema, lo que sería una pena volver a escribir todo, probé updateOne y encuentro el mismo resultado. También probé esto:
... try { const user = await User.findOneAndUpdate( { _id: userId }, { $set: { characteristics: { gender: newGender } } } ); ...y también:
try { const user = await User.findOneAndUpdate( { _id: userId }, { characteristics: {$set { gender: newGender } } } );Y ambos ejemplos también repiten el mismo patrón.
Esta no es una forma correcta de actualizar el valor del object .
Prueba esto:
exports.changeSex = async (req, res, next) => { // Requirements const userId = req.params.userId; const newGender = req.body.gender; console.log('userId: ' + userId); console.log('newGender: ' + req.body.gender); try { const user = await User.findOneAndUpdate( { _id: userId }, { $set: { "characteristics.gender": newGender } }, { returnDocument: 'after' } ); console.log('User successfully updated.',user); return res.status(200).json({ success: true, gender: newGender }); } catch (err) { console.log('ERROR: ', err); return res.status(400).json({ success: false, error: err }); } };{ returnDocument: 'after' } son opciones de consulta. es el documento de devolución después de la actualización.Si tiene alguna duda, vea el ejemplo: https://mongoplayground.net/p/w5WlqHxHghU