Вы можете сделать это двумя способами:
1 . Используя конвейер агрегации в обновлениях, которые доступны начиная с MongoDB v 4.0
, вы можете добиться всего за один вызов БД:
Запрос:
db.collection.update(
{ $or: [{ user_id: 3 }, { "notification.follower_id": 3 }] },
[
{$addFields: {user_img: {$cond: [ { $eq: ["$user_id", 3] }, "latest_path/to/own/img", "$user_img"]}}},
{
$addFields: {
notification: {
$cond: [
{ $eq: [{ $type: "$notification" }, "array"] }, /** This condition is to check 'notification' is an array or not */
{
$map: {
input: "$notification",
in: {
$cond: [
{ $eq: ["$$this.follower_id", 3] },
{ $mergeObjects: [ "$$this",{ img: "latest_path/to/own/img" }]},
"$$this",
]
}
}
},
"$$REMOVE",
],
}
}
}
],
{ multi: true }
);
Примечание: Этот $cond
для проверки, является ли «уведомление» массивом, может быть необязательным, если вы можете добавить третью ступень { $addFields : {notification: { $ifNull: [ '$notification', '$$REMOVE' ] }}}
.
2 . Другим способом вы могли бы сделать это обновление, используя два вызова БД:
Шаг 1: Обновить img
путь для родительского документа:
db.collection.updateOne({"user_id" : 3}, {$set : {user_img: "latest_path/to/own/img"}})
Шаг 2: Обновите img
путь для всех поддокументов в массиве «уведомлений», где follower_id : 3
:
db.collection.updateMany({"notification.follower_id" : 3}, {$set : {'notification.$.img': "latest_path/to/own/img"}})
Итак, все, что вы считаете наиболее подходящими для ваших нужд, может быть применено, но я предложил бы иметь индекс для user_id
field & notification
объектов массива и проверить производительность вашего запроса. Также вы можете попробовать findOneAndUpdate
или findAndModify
для возврата обновленных документов.
Ссылка: MongoDB-Documentation