Как выбрать плоскую структуру двухуровневой модели в MongoDB? - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть модель двухуровневой структуры в 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, но он по-прежнему содержит двухуровневую структуру в результатах.

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Это поможет:

Родительские и дочерние объекты отдельно обрабатываются как два аспекта.В конце оба результата объединяются в один массив, который затем разматывается, чтобы выдать все как отдельные документы.

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"
    }
}
)
0 голосов
/ 20 сентября 2018

Все, что вам нужно сделать, это:

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
    }
})
0 голосов
/ 20 сентября 2018

Вы можете попробовать ниже агрегации

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" }}
])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...