MongoDb - 如何在使用查找聚合时仅 return 嵌套子文档的字段?

MongoDb - How to only return field of nested subdocument when using lookup aggregation?

我对 MongoDb 很陌生,所以我习惯了 SQL。 现在我的数据库中有两个 collections:

1) 系列(具有嵌套的子文档)

2)评论(决定引用剧集子文档,因为会有很多评论)

查看这张图片可以更好地理解。

现在我要实现以下目标。对于每条评论(在本例中为两条),我想获取剧集名称。

我尝试了以下方法:

db.review.aggregate([  
   {  
      $lookup:{  
         from:"series",
         localField:"episode",
         foreignField:"seasons.episodes._id",
         as:"episode_entry"
      }
   }
]).pretty()

问题是这个 returns(当然)不仅是引用剧集的标题,而且 returns 整季文档。

我目前的输出见下图

不知道怎么实现。请帮我。 我正在使用 Mongo 3.4.9

我会推荐以下系列结构,它将季节数组展开为多个文档,每个季节一个。

这将帮助您直接 inserting/updating 剧集。

类似于

db.series.insertMany([
  {
    "title": "Sherlock Holmes",
    "nr": 1,
    "episodes": [
      {
        "title": "A Study in Pink",
        "nr": 1
      },
      {
        "title": "The Blind Banker",
        "nr": 2
      }
    ]
  },
  {
    "title": "Sherlock Holmes",
    "nr": 2,
    "episodes": [
      {
        "title": "A Scandal in Belgravia",
        "nr": 1
      },
      {
        "title": "The Hounds of Baskerville",
        "nr": 2
      }
    ]
  }
])

查找查询会做这样的事情

episode: { $in: [ episodes._id1, episodes._id2, ... ] }

来自文档

If the field holds an array, then the $in operator selects the documents whose field holds an array that contains at least one element that matches a value in the specified array (e.g. , , etc.)

所以当有匹配项时,查找将 return 所有剧集。然后您可以过滤以仅保留与您的评论剧集相匹配的那一集。

所以查询看起来像

db.review.aggregate([
  {
    "$lookup": {
      "from": "series",
      "localField": "episode",
      "foreignField": "episodes._id",
      "as": "episode_entry"
    }
  },
  {
    "$addFields": {
      "episode_entry": [
        {
          "$arrayElemAt": {
            "$filter": {
              "input": {
                "$let": {
                  "vars": {
                    "season": {
                      "$arrayElemAt": [
                        "$episode_entry",
                        0
                      ]
                    }
                  },
                  "in": "$$season.episodes"
                }
              },
              "as": "result",
              "cond": {
                "$eq": [
                  "$$result._id",
                  "$episode"
                ]
              }
            }
          }
        },
        0
      ]
    }
  }
])