MongoDB $ lookup для встроенных коллекций - PullRequest
2 голосов
/ 02 апреля 2020

У меня есть 2 коллекции:

UserCollection:

[
   {
      "_id" : ObjectId("3a9ccf7de6348936d88b3601"),
      "first_name" : "John",
   },
   {
       "_id" : ObjectId("3a9ccf7de6348936d88b3602"),
       "first_name" : "Jane",
   }
]

CommentCollection (со встроенным ReplyCollection):

[
   {
      "_id" : ObjectId("3a9ccf7de6348936d88b3601"),
      "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
      "body" : "Hello World",
      "replies":
      [
          {
             "_id" : ObjectId("3a9ccf7de6348936d88b3441"),
             "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
             "body" : "World said, Hello Back", 
          }
      ]
   },
   {
       "_id" : ObjectId("3a9ccf7de6348936d88b3602"),
       "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
       "body" : "Hello Stack",
       "replies":
       [
          {
             "_id" : ObjectId("3a9ccf7de6348936d88b3602"),
             "body" : "Stack said Overflow",
             "user_id": ObjectId("3a9ccf7de6348936d88b3601"),
          }
       ]
   }
]

Запрос на присоединение Комментарии и пользователи:

db.comments.aggregate([
   { "$lookup": {
     "from": "Users",
     "localField": "user_id",
     "foreignField": "_id",
     "as": "user" } 
   },
   {"$unwind": "$user"}
]);

Поведение : комментарии и таблица пользователей были объединены, как и ожидалось.

Вопрос : Можно ли также присоединить отношение «пользователь-ответ» в одном запросе?

Заранее спасибо.

1 Ответ

2 голосов
/ 02 апреля 2020

Да, вы можете сделать это, используя некоррелированный подзапрос в $lookup:

db.comments.aggregate([
  {
    $lookup: {
      from: "Users",
      let: {
        repliesUserId: "$replies.user_id",
        userId: "$user_id"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $or: [
                { $eq: ["$_id", "$$userId"] },
                { $in: ["$_id", "$$repliesUserId"] }
              ]
            }
          }
        }
      ],
      as: "user"
    }
  }
]);

Тест: MongoDB-Playground

...