Как увеличить поле в массиве объектов после его нахождения (с помощью findOne()) и перед его сохранением?

Я хочу обновить объект внутри массива схем без необходимости делать два запроса к базе данных. В настоящее время я увеличиваю поле с помощью findOneAndUpdate(), если объект уже существует, и он работает нормально. но в случае, если объект не существует, я должен сделать еще один запрос, используя update(), чтобы выдвинуть новый объект и сделать его доступным для последующих приращений.

Я хочу быть в состоянии сделать только один запрос (например, findOne()), чтобы получить пользователя, а затем увеличивать поле, только если объект существует в массиве, и если нет, я хотел бы вместо этого нажать новый объект. затем сохраните документ. таким образом я делаю только одно чтение / запрос из базы данных вместо двух.

это функция сейчас:

  async addItemToCart(body, userId) {
const itemInDb = await Model.findOneAndUpdate(
  {
    _id: userId,
    'cart.productId': body.productId,
  },
  { $inc: { 'cart.$.count': 1 } }
);
if (itemInDb) return true;

const updated = await Model.update(
  { _id: userId },
  { $push: { cart: body } }
);
if (updated.ok !== 1)
  return createError(500, 'something went wrong in userService');
return true;
}

что я хотел бы сделать, это:

  async addItemToCart(body, userId) {
const itemInDb = await Model.findOne(
  {
    _id: userId,
    'cart.productId': body.productId,
  }
);
if (itemInDb) {
  /**
   * 
   * increment cart in itemInDb then do itemInDb.save()  <<------------
   */
} else {
  /**
   * push product to itemInDb then save
   */
}

Спасибо!

2 ответа

Ты можешь попробовать findOneAndUpdate с upsert,

upsert: true затем создайте данные, если они не существуют в БД.

Model.findOneAndUpdate(
  {
    _id: userId,
    'cart.productId': body.productId,
  },
  { $inc: { 'cart.$.count': 1 } },
 {
     upsert: true,
   }
)

использование $set а также $inc в одном запросе.

try {
  db.scores.findOneAndUpdate(
    {
      _id: userId,
      'cart.productId': body.productId,
    },
     { $set: { "cart.$.productName" : "A.B.C", "cart.$.productPrice" : 5}, $inc : { "cart.$.count" : 1 } },
     { upsert:true, returnNewDocument : true }
  );
  }
  catch (e){
     //error
  }

Ссылка Ссылка: здесь

Вы можете использовать upsert.

upsert определяется как операция, которая создает новый документ, когда ни один документ не соответствует критериям запроса и, если соответствует, обновляет документ. Это опция для команды обновления. Если вы выполняете команду, подобную приведенной ниже, она работает как обновление, если есть запрос на сопоставление документа или как вставка с документом, описанным обновлением как аргумент.

Пример: я просто привожу простой пример. Вы должны изменить его в соответствии с вашими требованиями.

db.people.update(
   { name: "Andy" },
   {
      name: "Andy",
      rating: 1,
      score: 1
   },
   { upsert: true }
)

Таким образом, в приведенном выше примере, если люди с именем Andy найдены, будет выполнена операция обновления. Если нет, то он создаст новый документ.

Другие вопросы по тегам