如何加入多个 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
}
]
}
]
我想在类别方面获得所有 packages
和 items 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"
},
]
}
]
}
]
为了达到预期的结果,我们必须对数据执行一些步骤,我们将解释每个步骤。您可以看到完整的查询 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
}
}
这里我有三个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
}
]
}
]
我想在类别方面获得所有 packages
和 items 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"
},
]
}
]
}
]
为了达到预期的结果,我们必须对数据执行一些步骤,我们将解释每个步骤。您可以看到完整的查询 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
}
}