如何在MongoDB中选择两层模型的平面结构?
我在MongoDB中有一个两层结构模型,如下所示:如何在MongoDB中选择两层模型的平面结构?,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我在MongoDB中有一个两层结构模型,如下所示: export class ProductTypeModel { _id: ObjectID; name: string; children: { _id: ObjectID, name: string, icon: string }[]; } 它表示我的应用程序中的产品类型。实际上,子对象的属性与基本模型几乎相同,只是它有一个额外的图标属性 现在我有这样的数据:
export class ProductTypeModel {
_id: ObjectID;
name: string;
children: {
_id: ObjectID,
name: string,
icon: string
}[];
}
它表示我的应用程序中的产品类型。实际上,子对象
的属性与基本模型几乎相同,只是它有一个额外的图标
属性
现在我有这样的数据:
{
"_id" : ObjectId("5b9378d9a842a7557223ebfa"),
"name" : "Clothes",
"children" : [ {
"_id" : ObjectId("5b9378d9a842a7557223ebf6"),
"name" : "Men",
"icon": "xxx"
}, {
"_id" : ObjectId("5b9378d9a842a7557223ebf7"),
"name" : "Women",
"icon": "xxx"
}, {
"_id" : ObjectId("5b9378d9a842a7557223ebf8"),
"name" : "Shoes",
"icon": "xxx"
}, {
"_id" : ObjectId("5b9378d9a842a7557223ebf9"),
"name" : "Underwear",
"icon": "xxx"
} ]
}
我希望它们被选为:
[
{ "_id" : ObjectId("5b9378d9a842a7557223ebfa"), "name" : "Clothes", "parent": null },
{ "_id" : ObjectId("5b9378d9a842a7557223ebf6"), "name" : "Men", "icon": "xxx", "parent": ObjectId("5b9378d9a842a7557223ebfa") },
{ "_id" : ObjectId("5b9378d9a842a7557223ebf7"), "name" : "Women", "icon": "xxx", "parent": ObjectId("5b9378d9a842a7557223ebfa") },
{ "_id" : ObjectId("5b9378d9a842a7557223ebf8"), "name" : "Shoes", "icon": "xxx", "parent": ObjectId("5b9378d9a842a7557223ebfa") },
{ "_id" : ObjectId("5b9378d9a842a7557223ebf9"), "name" : "Underwear", "icon": "xxx", "parent": ObjectId("5b9378d9a842a7557223ebfa") }
]
在MongoDB中的一个查询中可以做到这一点吗
我尝试了
$unwind
,但结果中仍然包含两级结构。您可以在下面的聚合中尝试
db.collection.aggregate([
{ "$project": {
"data": {
"$map": {
"input": { "$concatArrays": ["$children", [{ "_id": "$_id", "name": "$name" }]] },
"in": {
"_id": "$$this._id",
"icon": "$$this.icon",
"name": "$$this.name",
"parent": { "$cond": [{ "$eq": ["$$this.icon", undefined] }, null, "$_id"] }
}
}
}
}},
{ "$unwind": "$data" },
{ "$replaceRoot": { "newRoot": "$data" }}
])
这将实现以下目的: 父对象和子对象分别作为两个面处理。最后,将两个结果合并到一个数组中,然后无意将所有内容作为单独的文档提供
db.collection.aggregate(
{
"$unwind": {
"path": "$children"
},
},
{
"$facet": {
"parentObjs": [
{
"$group": {
"_id": "$_id",
"name": { "$first": "$name" }
}
},
{
"$addFields": {
"parent": null
}
}
],
"childObjs": [
{
"$project": {
"_id": "$children._id",
"name": "$children.name",
"icon": "$children.icon",
"parent": "$_id"
}
}
]
}
},
{
"$project": { "items": { "$concatArrays": [ "$parentObjs", "$childObjs" ] } }
},
{
"$unwind": {
"path": "$items"
}
}
)
您需要做的就是:
db.collection.aggregate({
$addFields: {
"children.parent": "$_id" // push the "_id" field into every array element
}
}, {
$addFields: {
"children": { $concatArrays: [ "$children", [ { "_id": "$_id", "name": "$name", "parent": null } ] ] } // a the parent item into the "children" array
}
}, {
$unwind: "$children" // flatten the array
}, {
$replaceRoot: {
"newRoot": "$children" // move all content inside the "children" field to the top
}
})
对于顶层,父级需要为null。但我真的很喜欢地图的使用。我真正需要的是。。!将
$replaceRoot
与项一起使用