Добавьте псевдоним в коллекцию, предназначенную для поиска

#javascript #mongodb #mongoose #aggregation-framework

Вопрос:

Я новичок в MongoDB. Я постараюсь сделать все возможное, чтобы объяснить это как можно проще, поэтому я возьму пример коллекции в Интернете, а не более сложную схему, с которой я работаю!

У меня есть две коллекции следующим образом:

Пользователи:

 [
   {
     "_id":{"$oid":"610bcc467b0c4008346547b8"},
     "name":"xyz",
     "email":"xyz@gmail.com",
     "password":"xyz",
     "gender":"MALE"
   }
]
 

Публикации:

 [
   {
    "_id": {"$oid":"610bce417b0c4008346547bc"},
    "image":"myImage 1", 
    "caption":"r/Mars",
    "user_id":"610bcc467b0c4008346547b8"
   },
   { 
    "_id": {"$oid":"610bce417b0c4008346547be"},
    "image":"myImage 2", 
    "caption":"hmm",
    "user_id":"610bcc467b0c4008346547b8" 
   },
   { 
    "_id": {"$oid":"610bce417b0c4008346547bd"},
    "image":"myImage 3", 
    "caption":"..",
    "user_id":"610bcc467b0c4008346547b8"
   }
]
 

Я хочу объединить эти две коллекции с помощью $lookup . Поэтому я использую следующую агрегацию в коллекции пользователей:

 {
    '$addFields': {
        'userStrId': {
            '$toString': '$_id'
        }
    }
}, {
    '$lookup': {
        'from': 'posts', 
        'localField': 'userStrId', 
        'foreignField': 'user_id', 
        'as': 'user_posts'
    }
},
 

Раньше я $addFields добавлял _id поле пользователя в качестве строкового поля, чтобы я мог использовать его в $lookup ,

Генерируется следующий результат:

 [
   {
     "_id":{"$oid":"610bcc467b0c4008346547b8"},
     "name":"xyz",
     "email":"xyz@gmail.com",
     "password":"xyz",
     "gender":"MALE",
     "user_posts": [
        {
          "_id": {"$oid":"610bce417b0c4008346547bc"},
          "image":"myImage 1", 
          "caption":"r/Mars",
          "user_id":"610bcc467b0c4008346547b8"
        },
        { 
          "_id": {"$oid":"610bce417b0c4008346547be"},
          "image":"myImage 2", 
          "caption":"hmm",
          "user_id":"610bcc467b0c4008346547b8" 
        },
        { 
          "_id": {"$oid":"610bce417b0c4008346547bd"},
          "image":"myImage 3", 
          "caption":"..",
          "user_id":"610bcc467b0c4008346547b8"
        }
     ]
   }
]
 

Вопрос, который у меня сейчас возникает, заключается в том, как я могу добавить поле в каждый из документов user_posts таким образом, чтобы получить следующий результат:

 [
       {
         "_id":{"$oid":"610bcc467b0c4008346547b8"},
         "name":"xyz",
         "email":"xyz@gmail.com",
         "password":"xyz",
         "gender":"MALE",
         "user_posts": [
            {
              "_id": {"$oid":"610bce417b0c4008346547bc"},
              "image":"myImage 1", 
              "caption":"r/Mars",
              "user_id":"610bcc467b0c4008346547b8",
              "post_id":"610bce417b0c4008346547bc"
            },
            { 
              "_id": {"$oid":"610bce417b0c4008346547be"},
              "image":"myImage 2", 
              "caption":"hmm",
              "user_id":"610bcc467b0c4008346547b8",
              "post_id": "610bce417b0c4008346547be"
            },
            { 
              "_id": {"$oid":"610bce417b0c4008346547bd"},
              "image":"myImage 3", 
              "caption":"..",
              "user_id":"610bcc467b0c4008346547b8",
              "post_id":"610bce417b0c4008346547bd"
            }
         ]
       }
    ]
 

post_id добавляется в каждый из документов, и его значение равно значению _id этого документа, преобразованному в строку.

Ответ №1:

Вы можете добавить этап в конце этапов конвейера,

  • $map для повторения цикла user_posts
  • $mergeObjects для объединения текущего объекта user_posts и новых полей user_id и post_id
   {
    $addFields: {
      user_posts: {
        $map: {
          input: "$user_posts",
          in: {
            $mergeObjects: [
              "$this",
              {
                user_id: "$userStrId",
                post_id: { $toString: "$this._id" }
              }
            ]
          }
        }
      }
    }
  }
 

Игровая площадка