MongoDB聚合多次操作
MongoDB aggregation multiple operation
我有一个 items
collection:
[
{_id: '1', name: 'A', description: 'Some description 1'},
{_id: '2', name: 'B', description: 'Some description 2'},
{_id: '3', name: 'C', description: 'Some description 3'},
{_id: '4', name: 'D', description: 'Some description 4'},
]
我还有一个collectioncItems
:
[
{_id: '1', itemId: '1', items:[ {itemId: '2', qty: 4}, {itemId: '3', qty: 5} ]},
{_id: '2', itemId: '4', items:[ {itemId: '2', qty: 1}, {itemId: '3', qty: 1} ]},
]
我正在尝试使用聚合获取基于 itemId
in CItems
collection 的项目的详细信息。
cItems.aggregate([
{ $match: { _id: { $eq: categoryId } } },
{ $unwind: "$items" },
{
$lookup: {
from: "items",
let: {
itemId: "$items.itemId",
items: "$items",
},
pipeline: [
{ $match: { $expr: { $eq: ["$_id", "$$itemId"] } } },
{
$replaceRoot: {
newRoot: { $mergeObjects: ["$$items", "$$ROOT"] },
},
},
{
$project: {
qty: 1,
name: 1,
description: 1,
},
},
],
as: "items",
},
},
{
$group: {
_id: "$_id",
items: { $push: { $first: "$items" } },
name: { $first: "$name" },
description: { $first: "$description" },
},
},
]);
我得到的结果是:
{
"_id": "1",
"items": [
{
"qty": 4,
"_id": "2",
"name": "A",
"description": "Some description 2"
},
{
"qty": 5,
"_id": "3",
"name": "C",
"description": "Some description 3"
}
],
"name": null,
"description": null
}
问题是它为不在数组中的 itemId 的名称和描述显示空值。
预期输出:
{
"_id": "1",
"items": [
{
"qty": 4,
"_id": "2",
"name": "A",
"description": "Some description 2"
},
{
"qty": 5,
"_id": "3",
"name": "C",
"description": "Some description 3"
}
],
"name": 'A',
"description": "Some description 1"
}
我使用的是最新版本的MongoDB。
您错过了 $lookup
阶段,无法与 items
一起参加父项目 (itemId
) [第二阶段]。
要获取父项的名称和描述,您需要 $arrayElemAt
来获取 parentItem
[最后阶段] 的第一项。
解决方案 1
db.cItems.aggregate([
{
$match: {
_id: {
$eq: categoryId
}
}
},
{
$lookup: {
from: "items",
localField: "itemId",
foreignField: "_id",
as: "parentItem"
}
},
{
"$unwind": "$items"
},
{
$lookup: {
from: "items",
let: {
itemId: "$items.itemId",
items: "$items"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$_id",
"$$itemId"
]
}
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
"$$items",
"$$ROOT"
]
}
}
},
{
$project: {
qty: 1,
name: 1,
description: 1
}
}
],
as: "items"
}
},
{
$group: {
_id: "$_id",
items: {
$push: {
$first: "$items"
}
},
name: {
$first: {
"$arrayElemAt": [
"$parentItem.name",
0
]
}
},
description: {
$first: {
"$arrayElemAt": [
"$parentItem.description",
0
]
}
}
}
}
])
Sample Mongo Playground (Solution 1)
解决方案 2
db.cItems.aggregate([
{
$match: {
_id: {
$eq: categoryId
}
}
},
{
$lookup: {
from: "items",
localField: "itemId",
foreignField: "_id",
as: "parentItem"
}
},
{
$lookup: {
from: "items",
let: {
items: "$items"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$items.itemId"
]
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
{
$arrayElemAt: [
"$$items",
0
]
},
"$$ROOT"
]
}
}
}
],
as: "items"
}
},
{
$project: {
_id: 1,
itemId: 1,
items: 1,
name: {
$arrayElemAt: [
"$parentItem.name",
0
]
},
description: {
$arrayElemAt: [
"$parentItem.description",
0
]
}
}
}
])
我有一个 items
collection:
[
{_id: '1', name: 'A', description: 'Some description 1'},
{_id: '2', name: 'B', description: 'Some description 2'},
{_id: '3', name: 'C', description: 'Some description 3'},
{_id: '4', name: 'D', description: 'Some description 4'},
]
我还有一个collectioncItems
:
[
{_id: '1', itemId: '1', items:[ {itemId: '2', qty: 4}, {itemId: '3', qty: 5} ]},
{_id: '2', itemId: '4', items:[ {itemId: '2', qty: 1}, {itemId: '3', qty: 1} ]},
]
我正在尝试使用聚合获取基于 itemId
in CItems
collection 的项目的详细信息。
cItems.aggregate([
{ $match: { _id: { $eq: categoryId } } },
{ $unwind: "$items" },
{
$lookup: {
from: "items",
let: {
itemId: "$items.itemId",
items: "$items",
},
pipeline: [
{ $match: { $expr: { $eq: ["$_id", "$$itemId"] } } },
{
$replaceRoot: {
newRoot: { $mergeObjects: ["$$items", "$$ROOT"] },
},
},
{
$project: {
qty: 1,
name: 1,
description: 1,
},
},
],
as: "items",
},
},
{
$group: {
_id: "$_id",
items: { $push: { $first: "$items" } },
name: { $first: "$name" },
description: { $first: "$description" },
},
},
]);
我得到的结果是:
{
"_id": "1",
"items": [
{
"qty": 4,
"_id": "2",
"name": "A",
"description": "Some description 2"
},
{
"qty": 5,
"_id": "3",
"name": "C",
"description": "Some description 3"
}
],
"name": null,
"description": null
}
问题是它为不在数组中的 itemId 的名称和描述显示空值。
预期输出:
{
"_id": "1",
"items": [
{
"qty": 4,
"_id": "2",
"name": "A",
"description": "Some description 2"
},
{
"qty": 5,
"_id": "3",
"name": "C",
"description": "Some description 3"
}
],
"name": 'A',
"description": "Some description 1"
}
我使用的是最新版本的MongoDB。
您错过了 $lookup
阶段,无法与 items
一起参加父项目 (itemId
) [第二阶段]。
要获取父项的名称和描述,您需要 $arrayElemAt
来获取 parentItem
[最后阶段] 的第一项。
解决方案 1
db.cItems.aggregate([
{
$match: {
_id: {
$eq: categoryId
}
}
},
{
$lookup: {
from: "items",
localField: "itemId",
foreignField: "_id",
as: "parentItem"
}
},
{
"$unwind": "$items"
},
{
$lookup: {
from: "items",
let: {
itemId: "$items.itemId",
items: "$items"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$_id",
"$$itemId"
]
}
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
"$$items",
"$$ROOT"
]
}
}
},
{
$project: {
qty: 1,
name: 1,
description: 1
}
}
],
as: "items"
}
},
{
$group: {
_id: "$_id",
items: {
$push: {
$first: "$items"
}
},
name: {
$first: {
"$arrayElemAt": [
"$parentItem.name",
0
]
}
},
description: {
$first: {
"$arrayElemAt": [
"$parentItem.description",
0
]
}
}
}
}
])
Sample Mongo Playground (Solution 1)
解决方案 2
db.cItems.aggregate([
{
$match: {
_id: {
$eq: categoryId
}
}
},
{
$lookup: {
from: "items",
localField: "itemId",
foreignField: "_id",
as: "parentItem"
}
},
{
$lookup: {
from: "items",
let: {
items: "$items"
},
pipeline: [
{
$match: {
$expr: {
$in: [
"$_id",
"$$items.itemId"
]
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
{
$arrayElemAt: [
"$$items",
0
]
},
"$$ROOT"
]
}
}
}
],
as: "items"
}
},
{
$project: {
_id: 1,
itemId: 1,
items: 1,
name: {
$arrayElemAt: [
"$parentItem.name",
0
]
},
description: {
$arrayElemAt: [
"$parentItem.description",
0
]
}
}
}
])