为什么 $lookup 中的 "as" 正在替换完整集?

Why "as" in $lookup is replacing the complete set?

先介绍一下我用的2 collections :

Collection 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"
}

Collection 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 个 Collection(posts) 中的评论数组中的用户替换为撰写该评论的用户。

我试过下面的查询,但它正在替换评论部分!

 > 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 部分中获得详细信息,这样我就可以看到评论和发表该评论的用户。

你需要先展开评论数组

您的查询可能看起来像这样

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"
      }
    }
  }
])

你可以test it here

希望对您有所帮助

你可以在投影中处理它。

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 ] },
                     }
                 }
             }
         ])