如何加入多个 mongoDB Collections

How to join multiple mongoDB Collections

这里我有三个collection。

类别

category: [
    {
      id: 1,
      name: "cat 1",
      status:true
    },
    {
      id: 2,
      name: "cat 2",
      status:true
    }
  ]

项目

item: [
    {
      id: 1,
      name: "item 1"
    },
    {
      id: 2,
      name: "item 2"
    },
    {
      id: 3,
      name: "item 3"
    },
    {
      id: 4,
      name: "item 4"
    }
  ]

套餐

[
    {
      id: 1,
      name: "package 1",
      categoryId: 1,
      items: [
        {
          _id: 1,
          itemId: 1
        },
        {
          _id: 2,
          itemId: 2
        }
      ]
    },
    {
      id: 2,
      name: "package 2",
      categoryId: 2,
      items: [
        {
          _id: 1,
          itemId: 3
        },
        {
          _id: 2,
          itemId: 4
        }
      ]
    }
  ]

我想在类别方面获得所有 packagesitems object,并且每个类别状态都应该为真。我想根据类别列出所有包。

collection 包的列 CategoryId 是外键。

collection 包的列 ItemId 是外键。

预期输出

[
    {
        name:'cat 1',
        status:true,
        package:[
            {
                id: 1,
                name: "package 1",
                categoryId: 1,
                items: [
                    {
                        id: 1,
                        name: "item 1"
                    },
                    {
                        id: 2,
                        name: "item 2"
                    },
                ]
            }
        ]
    },
    {
        name:'cat 2',
        status:true,
        package:[
            {
                id: 2,
                name: "package 2",
                categoryId: 2,
                items: [
                    {
                        id: 3,
                        name: "item 3"
                    },
                    {
                        id: 4,
                        name: "item 4"
                    },
                ]
            }
        ]
    }
]

供参考:https://mongoplayground.net/p/83z0Hcgh04i

为了达到预期的结果,我们必须对数据执行一些步骤,我们将解释每个步骤。您可以看到完整的查询 here.

我们必须在 category 数据库上使用的操作是 aggregation

db.category.aggregate([])

在这个函数中,我们将把每一步都放在数组中。 第一个是 lookup,我们将获取与每个类别匹配的包并将它们存储在 packages 字段

{
    "$lookup": {
      "from": "package",
      "localField": "id",
      "foreignField": "categoryId",
      "as": "packages"
    }
}

由于我们需要物品信息来填充每个物品并且物品在每个包裹内,我们必须将它们分开。我们将 unwind 包裹和物品。

  {
    "$unwind": "$packages"
  },
  {
    "$unwind": "$packages.items"
  }

现在我们可以将每个项目与他的信息匹配,与另一个 lookup 并将它们存储在每个包裹中。

  {
    "$lookup": {
      "from": "items",
      "localField": "packages.items.itemId",
      "foreignField": "id",
      "as": "packages.items"
    }
  }

因为 lookup 给了我们一个数组,我们将使用另一个 unwind 来确保在摸索之前每个文档只有一个项目。

  {
    "$unwind": "$packages.items"
  }

此时我们已经有了所有想要的日期,但我们必须再次将其分组,因为我们之前用 unwind 将其分开。为了执行此操作,我们将在 packages.id 上使用 group。我们将格式化我们想要的字段,将所有项目放在一起并在 root 字段中保存一些辅助数据以备后用。

  {
    "$group": {
      "_id": "$packages.id",
      name: {
        "$first": "$packages.name"
      },
      "brandId": {
        "$first": "$packages.brandId"
      },
      "categoryId": {
        "$first": "$packages.categoryId"
      },
      root: {
        "$first": "$$ROOT"
      },
      "items": {
        "$push": "$packages.items"
      }
    }
  }

在这一步,我们将所有包放在一起,我们必须group获得category。为此,我们将使用 root.

中的辅助数据存储
  {
    "$group": {
      "_id": "$root.id",
      name: {
        "$first": "$root.name"
      },
      "packages": {
        "$push": "$$ROOT"
      }
    }
  }

最后我们将擦除辅助 root 字段。

  {
    "$project": {
      "packages.root": 0
    }
  }