обновление только одного элемента во вложенном документе json с помощью mongoose - PullRequest
1 голос
/ 05 марта 2020

Как я могу обновить только одну часть документа с Mon goose, когда вложены элементы json?

Я хотел бы обновить документ и просто установить «darkMode» из false правда, без ПОЛУЧЕНИЯ и ПОСТАВКИ всей "оседающей" части. Возможно ли это с пн goose?

        "settings": {
            "darkMode": false,
            "tipOfTheDay": true,
            "paperFormat": "DINA4",
        },

Если я УСТАНАВЛИВАЮ это, я потеряю все в части «настройки» документа:

        "settings": {
            "darkMode": true,
        },

My NodeJS Бэкэнд выглядит так. Я использую findByIdAndUpdate в данный момент. Может быть, есть лучший метод?

exports.updateProfile = async (req, res, next) => {
    const profile = await Profile.findByIdAndUpdate(req.params.id, req.body, {
        new: true,
        runValidators: true
    });

    if (!profile) {
        return res.status(400).json({success: false});
    }

    res.status(200).json({success: true, data: profile});
}

1 Ответ

1 голос
/ 05 марта 2020

Чтобы обновить поле во внедренном документе, вы должны использовать оператор $set (поскольку ваш документ - это объект, мы имеем дело с объектом внутри объекта)

Из документации mongodb:

https://docs.mongodb.com/v2.4/reference/method/db.collection.update/#update -specifi c -fields-in-Встроенные-документы

Обновить Specifi c Поля во встроенных документах Используйте точечную нотацию для обновить значения во встроенных документах.

Так что для вас, , если мы предположим, что req.body здесь { darkMode: true }, это будет

    const profile = await Profile.findByIdAndUpdate(
     req.params.id, 
     { $set: { 'settings.darkMode': req.body.darkMode } }, 
     {
        new: true,
        runValidators: true
    });

Но все зависит от того, как вы отправляете данные от клиента; если вы отправляете объект, содержащий только измененные поля, то вы должны специально установить $ set, чтобы сохранить другое значение без изменений, как описано выше. Чтобы автоматизировать это, вы также можете создать свой запрос, используя причудливый l oop:

let query = { $set: {} }

Object.keys(req.body).forEach(requestBodyKey => {
    let requestBodyFieldValue = req.body[requestBodyKey];
    query.$set[`settings.${requestBodyKey}`] = requestBodyFieldValue;
})

. Или вы можете сначала запросить свой документ, чтобы получить current_settings, затем, используя javascript, вы объедините два объекта ( например, {...myCurrentSettings, ...myNewerSettings } см. оператор распространения или Object.assign () ), а затем обновите его, чтобы обеспечить сохранение предыдущих, нетронутых значений полей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...