首页 > 解决方案 > 如何添加具有匹配文档的嵌入字段

问题描述

我正在使用 Python 和 pymongo 从数据库中查询。

我有 3 个不同的集合:

第一个:

# Projects collection
{
    "_id": "A",
},
{
    "_id": "B",
},
{
    "_id": "C"
},
..

第二:

# Episodes collection
{
    "_id": "A/Episode01",
    "project": "A",
    "name": "Episode01"
},
{
    "_id": "A/Episode02",
    "project": "A",
    "name": "Episode02"
},
{
    "_id": "B/Episode01",
    "project": "B",
    "name": "Episode01"
},
..

第三:

# Sequences collection
{
    "_id": "A/Episode01/Sequence01",
    "project": "A",
    "episode": "Episode01",
    "name": "Sequence01"
},
{
    "_id": "A/Episode02/Sequence02",
    "project": "A",
    "episode": "Episode02",
    "name": "Sequence02"
},
{
    "_id": "B/Episode01/Sequence01",
    "project": "B",
    "episode": "Episode01",
    "name": "Sequence01"
},
..

我想使用聚合来查询项目A并获取其所有相应的剧集和序列,如下所示:

{
    "_id": "A",
    "episodes": 
    [
        {
            "_id": "A/Episode01",
            "project": "A",
            "name": "Episode01",
            "sequences": 
            [
                {
                    "_id": "A/Episode01/Sequence01",
                    "project": "A",
                    "episode": "Episode01",
                    "name": "Sequence01"
                },
            ]
        },
        {
            "_id": "A/Episode02",
            "project": "A",
            "name": "Episode02",
            "sequences":
            [
                {
                    "_id": "A/Episode02/Sequence02",
                    "project": "A",
                    "episode": "Episode02",
                    "name": "Sequence02"
                },
            ]
        },
    ]
}

我可以得到正确的剧集,但我不确定如何为任何匹配的序列添加嵌入字段。是否可以在单个管道查询中完成所有这些操作?

现在我的查询看起来像这样:

[
    {"$match": {
        "_id": "A"}
    },
    {"$lookup": {
        "from": "episodes",
        "localField": "_id",
        "foreignField": "project",
        "as": "episodes"}
    },
    {"$group": {
        "_id": {
            "_id": "$_id",
            "episodes": "$episodes"}
    }}
]

标签: mongodbaggregation-frameworkpymongo

解决方案


你可以这样做

  1. 用于$match匹配文档
  2. 使用不相关的查询来加入两个集合。但正如您所写的,正常加入也是可能的。当我们遇到一些复杂的情况时,这会更容易。

Mongo脚本如下

[
  {
    "$match": {
      "_id": "A"
    }
  },
  {
    $lookup: {
      from: "Episodes",
      let: {
        id: "$_id"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $eq: [
                "$project",
                "$$id"
              ]
            }
          }
        },
        {
          $lookup: {
            from: "Sequences",
            let: {
              epi: "$name"
            },
            pipeline: [
              {
                $match: {
                  $expr: {
                    $eq: [
                      "$episode",
                      "$$epi"
                    ]
                  }
                }
              }
            ],
            as: "sequences"
          }
        }
      ],
      as: "episodes"
    }
  }
]

工作蒙戈游乐场


更新01

使用标准查找

[
  {
    "$match": {
      "_id": "A"
    }
  },
  {
    "$lookup": {
      "from": "Episodes",
      "localField": "_id",
      "foreignField": "project",
      "as": "episodes"
    }
  },
  {
    $unwind: "$episodes"
  },
  {
    "$lookup": {
      "from": "Sequences",
      "localField": "episodes.name",
      "foreignField": "episode",
      "as": "episodes.sequences"
    }
  },
  {
    $group: {
      _id: "$episodes._id",
      episodes: {
        $addToSet: "$episodes"
      }
    }
  }
]

工作蒙戈游乐场


推荐阅读