MongoDB聚合 互动版

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

$unwind拆分

拆分(unwind)可以将数组中的每一个值拆分为单独的文档。

例如,如果有一篇拥有多条评论的博客文章,可以使用$unwind将每条评论拆分为一个独立的文档:

db.blog.findOne()
{
   "_id":ObjectId("5359f6f6ec7452081a7873d7"),
   "author":"Tom",
   "conments":[
      {
          "author":"Mark",
          "date":ISODate("2014-01-01T17:52:04.148Z"),
          "text":"Nice post"
      },
      {
          "author":"Bill",
          "date":ISODate("2014-01-01T17:52:04.148Z"),
          "text":"I agree"
      }
   ]
}

db.blog.aggregate({"$unwind":"$comments"})

{
   "results":
       {
          "_id":ObjectId("5359f6f6ec7452081a7873d7"),
          "author":"Tom",
          "comments":{
               "author":"Mark",
               "date":ISODate("2014-01-01T17:52:04.148Z"),
               "text":"Nice post"
          }
       },
       {
          "_id":ObjectId("5359f6f6ec7452081a7873d7"),
          "author":"Tom",
          "comments":{
               "author":"Bill",
               "date":ISODate("2014-01-01T17:52:04.148Z"),
               "text":"I agree"
          }
       }
}

如果希望在查询中得到特定的子文档,这个操作符就会非常有用:先使用"$unwind"得到所有子文档,再使用"$match"得到想要的文档。例如,如果要得到特定用户的所有评论(只需要得到评论,不需要返回评论所属的文章),使用普通的查询是不可能做到的。但是,通过提取、拆分、匹配、就很容易了:

db.blog.aggregate({"$project":{"coomments":"$comments"}},
   {"$unwind":"$comments"},
   {"$match":{"comments.author":"Mark"}})

由于最后得到的结果仍然是一个"comments"子文档,所以你可能希望再做一次投射,以便让输出结果更优雅。