查找后在对象数组中设置字段。 MongoDb

set field in array of objects after lookup. MongoDb

我有两个合集 usersposts

users 有这样的文档:

{
  _id: ObjectId('611142303c409b5dc826e563'),
  name: 'foo'
}

posts 有这样的文档:

{
  _id: ObjectId('611142303c409b5dc826e111'),
  comments:[
    {
      owner: ObjectId('611142303c409b5dc826e563'),
      description: "my description"
    },
    {
      owner: ObjectId('611142303c409b5dc826e333'),
      description: "my description2"
    }
  ]
}

当我收到服务器端的请求时,我需要 return 所有者的整个文档,而不仅仅是它的 ID。

例如,对于获取请求,我必须 return:

{
  _id: ObjectId('611142303c409b5dc826e111'),
  comments:[
    {
      owner:{
        _id: ObjectId('611142303c409b5dc826e563'),
        name: 'foo'
    },
      description: "my description"
    },
    {
      owner:     {
        _id: ObjectId('611142303c409b5dc826e555'),
        name: 'foo2'
      },
      description: "my description2"
    }
  ]
}

为此,我执行了以下管道:

[
  $lookup:{
    from: 'owners',
    localField: 'comments.owner',
    foreignField: '_id',
    as: 'owners_comments'
  }
]

这样做我得到了一组在一个特定文档中有评论的所有者。

我的问题是如何为每个评论获取正确的所有者个人资料?我知道我可以更轻松地在服务器端做,但我更喜欢在数据库端做。

我想映射每个评论并在内部过滤 owners_comments,但我在 mongo 聚合中几乎没有问题。

你有什么建议吗?

你必须$unwind评论数组,然后才执行$lookup然后你想$group恢复原来的结构,像这样:

db.posts.aggregate([
  {
    $unwind: "$comments"
  },
  {
    $lookup: {
      from: "owners",
      localField: "comments.owner",
      foreignField: "_id",
      as: "owners"
    }
  },
  {
    $group: {
      _id: "$_id",
      comments: {
        $push: {
          owner: "$comments.owner",
          description: "$comments.description",
          owner_profile: {
            "$arrayElemAt": [
              "$owners",
              0
            ]
          },
          
        }
      }
    }
  }
])

Mongo Playground