提问人:skumy 提问时间:11/15/2023 最后编辑:Yong Shunskumy 更新时间:11/16/2023 访问量:83
嵌套级别的 MongoDB 聚合
MongoDB Aggregation on nested levels
问:
我使用MongoDB 4.4。
我正在尝试进行一个 Mongo 聚合查询,该查询将返回一个带有嵌套数组的文档。要指定上下文,请执行以下操作: 我有报价,其中包含模块,其中包含项目,这些项目本身包含注释。我为每个实体都有一个集合:
offers: {
_id: '64a6c6ed3f24ff001b74cf9d',
name: 'offer name',
}
modules: {
_id: '64a6c6ed3f24ff001b74cfab',
name: 'module name',
offerId: '64a6c6ed3f24ff001b74cf9d',
}
items: {
_id: '5e984aea5e6df000399e6b97',
name: 'module name',
moduleId: '64a6c6ed3f24ff001b74cfab',
}
notes: {
_id: '64c78caf0e5791001b15833c',
name: 'note name',
itemId: '5e984aea5e6df000399e6b97',
}
在我的查询中,我想通过 检索选件,此查询返回选件及其模块、每个模块的项以及每个项的注释。基本上是这样的对象:_id
offer: {
_id: "64a6c6ed3f24ff001b74cf9d",
name: "offer name",
modules: [
{
_id: "64a6c6ed3f24ff001b74cfab",
name: "module name",
items: [
{
_id: "5e984aea5e6df000399e6b97",
name: "item name",
notes: [
{
_id: "64c78caf0e5791001b15833c",
name: "note name"
},
{
// other note
},
...
]
},
{
// other item
},
...
]
},
{
// other module
},
...
]
}
我写了这个查询:
db.getCollection("offers").aggregate([
{
$match: {
_id: ObjectId('64a6c6ed3f24ff001b74cf9d'),
}
},
{
$lookup: {
from: 'modules',
localField: '_id',
foreignField: 'offerId',
as: 'modules',
},
},
{
$unwind: '$modules',
},
{
$lookup: {
from: 'items',
localField: 'modules._id',
foreignField: 'moduleId',
as: 'items',
},
},
{
$unwind: '$items',
},
{
$lookup: {
from: 'notes',
localField: 'items._id',
foreignField: 'itemId',
as: 'notes',
},
},
{
$group: {
_id: "$_id",
name: { $first: "$name" },
modules: {
$push: {
_id: "$modules._id",
name: "$modules.name",
items: {
$push: {
_id: "$items._id",
name: "$items.name",
notes: {
$push: {
_id: "$notes._id",
name: "$notes.name",
}
},
}
},
}
}
}
},
{
$project: {
_id: 1,
name: 1,
modules: 1,
}
},
]);
但是当我运行它时,我收到此错误:
无法识别的表达式“$push”
嵌套(es)是不可能的吗?在这种情况下,如何达到预期的结果?$push
提前致谢。
答:
1赞
Joe
11/16/2023
#1
聚合运算符在嵌套值中无效。要获得所需的结果,请为每个级别使用单独的$group,例如:$push
{$group:{
_id:{
_id:"$_id",
module:{_id:"$modules._id", name:"$modules.name"},
item:{_id:"$garantyItems._id", name:"$garantyItems.name"}
},
notes:{$push:{ _id:"$notes._id", name:"$notes.name"}}
}},
{$group:{
_id:{
_id:"$_id._id",
module:"$_id.module",
},
items:{$push:{_id:"$_id.item._id",name:"$_id:item.name",notes:"$notes"}}
}},
{$group:{
_id:"$_id._id",
modules:{$push:{_id:"$_id.module._id",name:"$_id.module.name",items:"$items"}}
}}
1赞
Yong Shun
11/16/2023
#2
根据评论中提到的@user20042973,嵌套阶段应该更容易加入嵌套数组中的多个集合并自定义其投影。$lookup
db.offers.aggregate([
{
$match: {
_id: ObjectId("64a6c6ed3f24ff001b74cf9d")
}
},
{
$lookup: {
from: "modules",
localField: "_id",
foreignField: "offerId",
pipeline: [
{
$lookup: {
from: "items",
localField: "_id",
foreignField: "moduleId",
pipeline: [
{
$lookup: {
from: "notes",
localField: "_id",
foreignField: "itemId",
pipeline: [
{
$unset: "itemId"
}
],
as: "notes"
}
},
{
$unset: "moduleId"
}
],
as: "items"
}
},
{
$unset: "offerId"
}
],
as: "modules"
}
}
])
评论
0赞
skumy
11/16/2023
感谢您的回复,它适用于 Mongo 6,但使用我的 Mongo 版本 (4.4) 我有一个错误:带有“pipeline”的$lookup可能不会指定“localField”或“foreignField”
1赞
Yong Shun
11/16/2023
嗨,@skumy,在这种情况下,您应该将查询修改为这个演示。
评论