代码之家  ›  专栏  ›  技术社区  ›  Mike Evers

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

  •  0
  • Mike Evers  · 技术社区  · 7 年前

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

    1) 序列(具有嵌套子文档)

    2) 复习(决定参考插曲子文档,因为会有很多复习)

    请参阅此图片以更好地理解。

    enter image description here

    现在我想实现以下目标。对于每一篇评论(本例中有两篇),我都想得到一集的名称。

    我尝试了以下方法:

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

    问题是,它(当然)不仅返回了引用集的标题,而且还返回了整个季度的文档。

    我的电流输出见下图。

    enter image description here

    我不知道如何实现它。请帮帮我。 我正在使用Mongo 3.4.9

    1 回复  |  直到 7 年前
        1
  •  1
  •   s7vr    7 年前

    我建议使用以下系列结构,将季节数组展开为多个文档,每个季节一个文档。

    这将帮助您直接插入/更新剧集。

    类似于

    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, ... ] }
    

    从文档中

    如果字段包含一个数组,则$in运算符选择 其字段包含至少包含一个数组的文档 与指定数组中的值匹配的元素(例如,等等)

    因此,当存在匹配时,查找将返回所有集。然后,您可以进行筛选,只保留与您的评论片段相匹配的内容。

    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
          ]
        }
      }
    ])