Как обновить только некоторые свойства объекта в базе данных MongoDB

1

Мой код ниже не позволяет пользователю API обновлять только одно поле, передавая одно свойство запроса. Я могу удалить нуль в userObj, но разработчик пользовательского интерфейса должен будет передать существующие данные из базы данных, чтобы сделать обновление, что не является лучшей практикой.

Вот мой экспресс-маршрут:

router.put('/user', (req, res) => {
  const userObj = {
    name: req.body.name || null,
    location: {
      city: req.body.city || null
      },
      phone: req.body.phone || null
    };

  User.updateUser(req.body.id, userObj)
});

Вот моя монгольская модель updateUser:

module.exports.updateUser = (_id, userObj, callback) => {
  User.findOneAndUpdate({_id}, userObj, { upsert: true, 'new': true }, callback);
}
Теги:
ecmascript-6
express
mongoose

2 ответа

4
Лучший ответ

Во-первых, чтобы решить проблему с обновлением только нескольких определенных свойств, вам нужно использовать оператор $set для установки только определенного поля. Когда вы передаете userObj прямо в findOneAndUpdate вы findOneAndUpdate весь объект, таким образом, вы должны передать все существующие свойства. Используйте $set:

User.findOneAndUpdate({_id}, { $set: userObj }, { upsert: true, new: true }, callback);

Это обновит только свойства, определенные в userObj к их новым значениям и больше ничего не коснется. Кроме того, вы можете просто использовать findByIdAndUpdate для этого самого случая использования:

User.findByIdAndUpdate(_id, { $set: userObj }, { upsert: true, new: true }, callback);

Затем вы не должны использовать PUT. Используйте PATCH. PUT означает размещение ресурса на каком-то URL-адресе и его замену полностью, если он уже существует. PATCH означает, что вы обновляете только несколько свойств ресурса и заменяете все это. Это не повлияет на функциональность приложения, но это огромная проблема семантики и проблема конечного пользователя, так как они ожидали бы PATCH.

  • 0
    так что нет разницы между использованием $ set и findByIdAndUpdate?
  • 2
    @JessieAnderson Есть. Всегда используйте $set независимо , если вы используете findByIdAndUpdate или findOneAndUpdate , если вы хотите обновить только один или более специфических свойств.
Показать ещё 3 комментария
0

Использовать $ set

User.findOneAndUpdate({_id}, {$set: userObj}, /* ... */)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню