Как обновить вложенный объект в коллекции MongoDB на основе запроса?

#javascript #node.js #database #mongodb #mongoose

Вопрос:

У меня есть коллекция для пользователя, приведенная ниже

 {
  "_id": 1
  "firstname": "John"
  "lastname": "Doe"
  "address": {
    "street": "13",
    "city": "Los Angeles",
    "state": "California",
    "country": "USA",
    "pincode": "12345"
  }
}
 

Я хочу создать API, который будет обновлять пользовательские данные.

Это то, что я пробовал:

Первый Способ

С помощью этого метода из коллекции удаляются некоторые поля, которых нет в запросе.

Запрос:

 const updateUser = (userId, data) => {
    return UserDB.updateOne({ _id: userId }, {
        $set: {...data }
    });
};
 

Запрос:

 {
  "_id": 1
  "firstname": "Justin"
  "lastname": "Thomas"
  "address": {
    "country": "Canada",
    "pincode": "9999"
  }
}
 

Результат:

 // street, city and state is removed from collection
{
  "_id": 1
  "firstname": "Justin"
  "lastname": "Thomas"
  "address": {
    "country": "Canada",
    "pincode": "9999"
  }
}
 

Второй Способ:

При использовании этого метода полям присваивается значение null, которого нет в запросе.

Запрос:

 const updateUser = (userId, data) => {
    return UserDB.updateOne({ _id: userId }, {
        $set: {
            "firstname": data.firstname,
            "lastname": data.lastname,
            "address.street": data.address.street,
            "address.city": data.address.city,
            "address.state": data.address.state,
            "address.country": data.address.country,
            "address.pincode": data.address.pincode
        }
    });
};
 

Запрос:

 {
  "_id": 1
  "firstname": "Justin"
  "lastname": "Thomas"
  "address": {
    "country": "Canada",
    "pincode": "9999"
  }
}
 

Результат:

 // street, city and state is set to null in the collection.
{
  "_id": 1
  "firstname": "Justin"
  "lastname": "Thomas"
  "address": {
    "street": null,
    "city": null,
    "state": null,
    "country": "Canada",
    "pincode": "9999"
  }
}
 

Вопрос

Как я могу обновить вложенный объект в коллекции?

Комментарии:

1. Если я правильно понял вашу проблему, вы можете использовать точечную нотацию, чтобы не перезаписывать весь документ. Проверьте этот пример.

2. Недостаточно информации, чтобы понять, в чем причина вашей проблемы. Было бы более полезно знать, что data содержится в параметре updateUser функции.

3. data состоит из объекта запроса, упомянутого в вопросе

Ответ №1:

Второй способ работает нормально, пожалуйста, проверьте свои данные.

Комментарии:

1. Это работает, потому что точечная нотация, обратите внимание, как не работает использование объекта

2. @Arvind Pal Попробуйте удалить любое поле внутри адреса, например city или street . Он не будет обновляться в коллекции

3. Я обновил только пинкод и страну адреса, остальные, как и ранее.

4. То, что вы обновили, уже упомянуто во втором подходе моего вопроса.

Ответ №2:

Использование $addFields в конвейере агрегирования update операций.

$addFields будут обновлены только те значения, которые присутствуют в объекте, а другие поля останутся такими, как есть.

Подобный этому:

 db.collection.update({
  _id: 1
},
[
  {
    $addFields: {
      "firstname": "Justin",
      "lastname": "Thomas",
      "address": {
        "country": "Canada",
        "pincode": "16565"
      }
    }
  }
])
 

Проверьте это здесь: https://mongoplayground.net/p/pjO8mIKb03o