Почему "as" в $ lookup заменяет полный набор? - PullRequest
1 голос
/ 16 июня 2020

Позвольте мне сначала познакомить вас с 2 коллекциями, которые я использую:

Коллекция 1: пользователи

> db.users.find().pretty()
{
    "_id" : ObjectId("5ee4e727d04e4b4ac1ef115b"),
    "name" : "Ashutosh Tiwari",
    "age" : 21,
    "email" : "ashutosh@gmail.com"
}
{
    "_id" : ObjectId("5ee4e727d04e4b4ac1ef115c"),
    "name" : "Maximilian",
    "age" : 32,
    "email" : "max@yahoo.com"
}

Коллекция 2: сообщения

> db.posts.find().pretty()
{
    "_id" : ObjectId("5ee51b7ed9f661cad505fcc6"),
    "title" : "First One",
    "text" : "Hey this is the first Author",
    "author" : ObjectId("5ee4e727d04e4b4ac1ef115c"),
    "comments" : [
        {
            "user" : ObjectId("5ee4e727d04e4b4ac1ef115b"),
            "comment" : "This is my comment"
        }
    ]
}
{
    "_id" : ObjectId("5ee5353cd9f661cad505fcc8"),
    "title" : "First One",
    "author" : ObjectId("5ee4e727d04e4b4ac1ef115c"),
    "comments" : [
        {
            "user" : ObjectId("5ee4e727d04e4b4ac1ef115b"),
            "comment" : "This is my comment"
        }
    ]
}

Я хочу, чтобы пользователь внутри массива комментариев во 2-й подборке (сообщениях) был заменен пользователем, который написал этот комментарий.

Я пробовал запрос ниже, но он заменяет раздел комментариев!

 > db.posts.aggregate([
         { $lookup: 
                  {from: "users", 
                   localField:"comments.user",
                   foreignField:"_id",
                   as:"comments.user"
                   }   
         }  ]).pretty()

{
    "_id" : ObjectId("5ee51b7ed9f661cad505fcc6"),
    "title" : "First One",
    "text" : "Hey this is the first Author",
    "author" : ObjectId("5ee4e727d04e4b4ac1ef115c"),
    "comments" : {
        "user" : [
            {
                "_id" : ObjectId("5ee4e727d04e4b4ac1ef115b"),
                "name" : "Ashutosh Tiwari",
                "age" : 21,
                "email" : "ashutosh@gmail.com"
            }
        ]
    }
}
{
    "_id" : ObjectId("5ee5353cd9f661cad505fcc8"),
    "title" : "First One",
    "author" : ObjectId("5ee4e727d04e4b4ac1ef115c"),
    "comments" : {
        "user" : [
            {
                "_id" : ObjectId("5ee4e727d04e4b4ac1ef115b"),
                "name" : "Ashutosh Tiwari",
                "age" : 21,
                "email" : "ashutosh@gmail.com"
            }
        ]
    }
}

Итак, здесь весь раздел комментариев теперь заменен, тогда как я хотел, чтобы подробности были в разделе comments.user, чтобы я мог видеть комментарий и пользователя, который разместил этот комментарий.

Ответы [ 2 ]

1 голос
/ 16 июня 2020

Вы можете справиться с этим в проекции.

db.posts.aggregate([
         { $lookup: 
                  {from: "users", 
                   localField:"comments.user",
                   foreignField:"_id",
                   as:"cu"
                   }   
         },
         {$unwind:{path:"$cu"}},
         {
             $project:{
                 "title":1,
                 "text":1,
                 "author":1,
                 "comments":{
                     user: "$cu",
                     comment: { $arrayElemAt: [ "$comments.comment", 0 ] },
                     }
                 }
             }
         ])
1 голос
/ 16 июня 2020

сначала нужно развернуть массив комментариев

ваш запрос может выглядеть примерно так

db.posts.aggregate([
  {
    $unwind: "$comments" // unwind the comments array to get a stream of documents, each document has only one comment
  },
  {
    $lookup: {
      from: "users",
      localField: "comments.user",
      foreignField: "_id",
      as: "comments.user"
    }
  },
  {
    $unwind: "$comments.user" // we know there is only one user inside a single comment, so we can unwind this user array to be an object too (as the lookup returns an array)
  },
  {
    $group: { // then do a group by the document _id to get unique documents with comments array instead of the same document duplicated with different comments 
      _id: "$_id",
      author: {
        $first: "$author"
      },
      text: {
        $first: "$text"
      },
      title: {
        $first: "$title"
      },
      comments: {
        $push: "$comments"
      }
    }
  }
])

вы можете проверить его здесь

надеюсь, это поможет

...