首页 > 解决方案 > 在 mongodb 数组中查找嵌套字段

问题描述

架构

[
    {
        "_id" : ObjectId("60e09c90402cbd625d7a8162"),
        "title" : "...",
        "author" : DBRef("users", ObjectId("60ce9146f41866120ee70c0d")),
        "posts" : [ ]
    }
    {
        "_id" : ObjectId("60e09c97402cbd625d7a8163"),
        "title" : "...",
        "author" : DBRef("users", ObjectId("60ce9146f41866120ee70c0d")),
        "posts" : [ ]
    }
    {
        "_id" : ObjectId("60e09d06402cbd625d7a8164"),
        "title" : "...",
        "author" : DBRef("users", ObjectId("60ce9146f41866120ee70c0d")),
        "posts" : [ ]
    }
    {
        "_id" : ObjectId("60e09d07402cbd625d7a8165"),
        "title" : "...",
        "author" : DBRef("users", ObjectId("60ce9146f41866120ee70c0d")),
        "posts" : [
            {
                "_id" : ObjectId("60e12300e931cd14c03ecd89"),
                "title" : "...",
                "author" : DBRef("users", ObjectId("60ce9146f41866120ee70c0d"))
            },
            {
                "_id" : ObjectId("60e12305e931cd14c03ecd8a"),
                "title" : "...",
                "author" : DBRef("users", ObjectId("60ce9146f41866120ee70c0d"))
            }
        ]
    }
]

每个文档都有一个title,authorposts属性。author属性是$refposts属性是文档数组。每个文件posts也会有title, author

我想要的是

我想获取所有带有作者的文档,并且它是posts(带有作者)。

询问

db.blogs.aggregate([
  { $project: {title:1,author:1,"posts.title":1,"posts._id":1,"posts.author":1} },
  { "$lookup": { "from": "users", "localField": "author.$id", "foreignField": "_id", "as": "author" } },
  { "$lookup": { "from": "users", "localField": "posts.author.$id", "foreignField": "_id", "as": "posts.author" } }
])

回复

[
  {
    "_id": '..',
    "title": "..",
    "author": [
      {
        // author details
      }
    ],
    "posts": {
      "author": []
    }
  },
  {
    "_id": '..',
    "title": "...",
    "author": [
      {
        // author details
      }
    ],
    "posts": {
      "author": []
    }
  },
  {
    "_id": '..',
    "title": "..",
    "author": [
      {
        // author details
      }
    ],
    "posts": {
      "author": []
    }
  },
  {
    "_id": ...,
    "title": "2 Type SR Blog, my first blog.",
    "author": [
      {
        // author details
      }
    ],
    "posts": {
      "author": [
        {
        // author details
        }
      ]
    }
  }
]

用户集合

{
    "_id" : ObjectId("60ce9146f41866120ee70c0d"),
    "name" : "Rahul kumar",
    "status" : "A Fake Developer",
    "__v" : 0,
    "pic" : "https://res.cloudinary.com/bdevg/image/upload/v1604287418/pic_xexz8o.jpg"
}

问题

您可以看到最后一个文档,它只有posts属性。它还应该包含title属性。

标签: node.jsmongodbaggregation-framework

解决方案


  • $unwind解构posts数组
  • $lookupusers收集并作为posts.authorlocalField传递
  • $unwind解构author数组
  • $group通过_id并重建posts数组并获取其他必填字段的第一个值
  • $lookup使用usersauthor作为 localField传递
  • $unwind解构author数组
db.blogs.aggregate([
  {
    $unwind: {
      path: "$posts.author",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    "$lookup": {
      "from": "users",
      "localField": "posts.author",
      "foreignField": "_id",
      "as": "posts.author"
    }
  },
  {
    $unwind: {
      path: "$posts.author",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $group: {
      _id: "$_id",
      title: { $first: "$title" },
      posts: { $push: "$posts" },
      author: { $first: "$author" }
    }
  },
  {
    "$lookup": {
      "from": "users",
      "localField": "author",
      "foreignField": "_id",
      "as": "author"
    }
  },
  {
    $unwind: {
      path: "$author",
      preserveNullAndEmptyArrays: true
    }
  }
])

操场


推荐阅读