猫鼬嵌套查找,数组中包含 3 个子级别

Mongoose nested lookup with 3 child levels included in arrays

我是 MongoDB 和猫鼬的新手。

我正在尝试从数据库中检索整个对象层次结构数组作为 JSON。

通过搜索,我学会了如何在没有数组的情况下将嵌套查找与 3 个子级别分组,但问题是我找不到处理嵌套数组的方法。

这就是我正在努力解决的问题。

用户:

[
 {
  _id: ObjectId("a1"),
  username: "user1",
  name: "name1"
 },
 {
  _id: ObjectId("a2"),
  username: "user2",
  name: "name2"
 },
{
  _id: ObjectId("a3"),
  username: "user2",
  name: "name2"
 },
 ...
]

回复:

[
 {
  _id: ObjectId("a"),
  author: {ObjectId("a3")},
  title: {"Reply1"};
  body: {"Hello World!"}
 },
 {
  _id: ObjectId("b"),
  author: {ObjectId("a1")},
  title: {"Reply2"};
  body: {"Hello World!"}
 },
 {
  _id: ObjectId("c"),
  author: {ObjectId("a2")},
  title: {"Reply3"};
  body: {"Hello World!"}
 },
 {
  _id: ObjectId("d"),
  author: {ObjectId("a2")},
  title: {"Reply4"};
  body: {"Hello World!"}
 }
...
]

post:

[
//First post
 {
  _id: ObjectId("0"),
  title: 'post title',
  author: {ObjectId("a1")},
  reply: [{ObjectId("a")}, {ObjectId("b")}, ...],
 },
//Second Post
 {
  _id: ObjectId("1"),
  title: 'post title2',
  author: {ObjectId("a2")},
  reply: [{ObjectId("c")}, {ObjectId("d")}, ...],
 },
 ...
]

预期示例:

[
//First post
 {
  _id: ObjectId("0"),
  title: 'post title',
  author: {
   _id: ObjectId("a1"),
   username: "user1",
   name: "name1"
  },
  reply: [{
   _id: ObjectId("a"),
   author: {
    _id: ObjectId("a3"),
    username: "user2",
    name: "name2"
   },
   title: {"Reply1"},
   body: {"Hello World!"}
   }, 
   {
   _id: ObjectId("b"),
   author: {
    _id: ObjectId("a1"),
    username: "user1",
    name: "name1"
   },
   title: {"Reply2"};
   body: {"Hello World!"}
   },
   ...
  ],
 },
 {
 //Second post
 },
 ...
]

这是我使用的代码。

posts = await Post.aggregate([{
    $match: searchQuery
  },
  {
    $lookup: {
      from: 'users',
      localField: 'author',
      foreignField: '_id',
      as: 'author'
    }
  },

  {
    $lookup: {
      from: 'replies',
      localField: 'reply',
      foreignField: '_id',
      as: 'reply'
    }
  },
  {
    $unwind: '$author',
  },
  {
    $lookup: {
      from: 'users',
      localField: 'reply.author',
      foreignField: '_id',
      as: 'reply.author'
    }
  },
  {
    $project: {
      title: 1,
      author: 1,
      reply: 1
    }
  },
]).exec();

如果想得到预期的例子,应该怎么改代码呢? 谢谢。

这是一种方法。 post 的作者 "$lookup"postreplyreply 的作者 id,然后匹配 _id 的作者文档。

db.post.aggregate([
  {
    "$lookup": {
      "from": "user",
      "localField": "author",
      "foreignField": "_id",
      "as": "author"
    }
  },
  {
    "$set": {
      "author": {
        "$first": "$author"
      }
    }
  },
  {
    "$lookup": {
      "from": "reply",
      "localField": "reply",
      "foreignField": "_id",
      "as": "reply"
    }
  },
  {
    "$lookup": {
      "from": "user",
      "localField": "reply.author",
      "foreignField": "_id",
      "as": "replyAuthors"
    }
  },
  {
    "$project": {
      "title": 1,
      "author": 1,
      "reply": {
        "$map": {
          "input": "$reply",
          "as": "repObj",
          "in": {
            "$mergeObjects": [
              "$$repObj",
              {
                "author": {
                  "$first": {
                    "$filter": {
                      "input": "$replyAuthors",
                      "as": "repA",
                      "cond": {
                        "$eq": [
                          "$$repA._id",
                          "$$repObj.author"
                        ]
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
])

mongoplayground.net 上试用。