我在MongoDB中有一个两级结构模型,如下所示:
export class ProductTypeModel {
_id: ObjectID;
name: string;
children: {
_id: ObjectID,
name: string,
icon: string
}[];
}
它代表我的应用程序中的产品类型。实际上,children
具有与基本模型几乎相同的属性,只是它具有额外的icon
属性。
现在我有这样的数据:
{
"_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
,但结果中仍然包含两个级别的结构。
答案 0 :(得分:2)
您可以尝试以下汇总
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" }}
])
答案 1 :(得分:0)
这可以解决问题:
父对象和子对象分别作为两个方面处理。最后,将两个结果合并为一个数组,然后展开以将所有内容作为单独的文档提供。
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"
}
}
)
答案 2 :(得分:0)
您需要做的就是这个
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
}
})