MongoDB отношение один к одному - PullRequest
0 голосов
/ 09 апреля 2020

У меня следующая проблема: В моем mongoDB есть коллекция, где я храню своих пользователей. У каждого пользователя есть поле с именем notification и массив, в котором хранятся такие объекты, как:

user_id: 1,
user_img: "path/to/own/img",
notification: [
   {
      img: "path/to/user/img",
      message: "User XY added you.",
      follower_id: 3
   }
]

В этом примере пользователь получает уведомление о том, что пользователь с user_id 3 только что добавил его и с помощью img Я могу отобразить изображение пользователя.

Мой вопрос здесь: Как мне создать запрос, который получает user_img от заданного user_id? Потому что всякий раз, когда пользователь с user_id 3 меняет свой pi c, он также должен быть изменен в массиве уведомлений, чтобы отображать старую картинку пользователя.

enter image description here

1 Ответ

0 голосов
/ 09 апреля 2020

Вы можете сделать это двумя способами:

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

...