簡體   English   中英

使用MongoDB和Node.js進行類別層次結構聚合

[英]Category hierarchy aggregation using mongodb and nodejs

我的文檔結構如下:

{
    "_id" : ObjectId("54d81827e4a4449d023b4e34"),
    "cat_id" : 1,
    "description" : "Refridgerator",
    "image" : "refridgerator",
    "parent" : null,
    "slug" : "refridgerator"
}
{
    "_id" : ObjectId("54dc38bce4a4449d023b4e58"),
    "name" : "Ice Cream",
    "description" : "Ice Cream",
    "image" : "ice-cream.jpg",
    "slug" : "ice-cream",
    "parent" : "54d81827e4a4449d023b4e34"
}
{
    "_id" : ObjectId("54dc3705e4a4449d023b4e56"),
    "name" : "Chocolate",
    "description" : "Chocolate",
    "image" : "chocolate.jpg",
    "slug" : "chocolate",
    "parent" : "54d81827e4a4449d023b4e34"
}

我正在使用mongodb和nodejs創建類別層次結構。

現在我想查詢_id = '54d81827e4a4449d023b4e34' (Refridgerator),並且應該獲取所有子類別

如何在nodejs中實現以上?

另外,nodejs使用對數據庫的異步調用,我無法獲得具有父子關系的json結構。

我將如何對此進行異步調用?

這與NodeJS無關,重要的是您的數據結構。

請參閱我對這個問題的回答 ,第一部分是關於如何有效地實施它。

您想要冰箱和所有子類別嗎?

而且異步也是個問題嗎?

我認為您可以在此處使用聚合。

假設您正在尋找帶有_id變量的類別,該類別是所需的ObjectId,它是子類別。

db.yourCollection.aggregate({
    // get stuff where you have the parent or subcats.
    $match: {
         $or: [
               {_id: ObjectId("54de8b9f022ff38bbf5e0530")},
               {parent: ObjectId("54de8b9f022ff38bbf5e0530")}
              ]
         }
},
// reshape the data you'll need further on from each mached doc
{
    $project: {
        _id: false,
        data: {
            id: '$_id',
            name: '$name'
            // I guess you'll also want the `slug` and `image` here.
            // but that's homework :)
        },
        parent: '$parent'
    }
},
// now put a common _id so you can group them, and also put stuff into arrays
{
    $project: {
        id: {$literal: 'id'},
        mainCategory: {
            // if our parent is null, put our data.
            // otherwise put null here.
            $cond: [{$eq: [null, '$parent']}, {_id: '$data.id', name: '$data.name'}, undefined]
        },
        subcat: {
            // here is the other way around.
            $cond: [{$ne: [null, '$parent']}, {_id: '$data.id', name: '$data.name'}, null]

        }
    }
    // that stage produces for each doc either a mainCat or subcat
    // (and the other prop equals to null)
},
// finally, group the things so you can have them together
{
    $group: {
        _id: '$id',
        // a bit hacky, but mongo will yield to it
        mainCategory: {$max: '$mainCategory'},
        subCategories: {
            // this will, unfortunately, also add the `null` we have
            // assigned to main category up there
            $addToSet: '$subcat'
        }
    }
},
// so we get rid of the unwanted _id = 'id' and the null from subcats.
{
    $project: {
        _id: false,
        mainCategory: 1,
        subCategories: {
            $setDifference: ['$subCategories', [null]]
        }
    }
})

給定此數據集:

[{
    "_id" : ObjectId("54de8b9f022ff38bbf5e0530"),
    "name" : "Fridge",
    "parent" : null
},
{
    "_id" : ObjectId("54de8bba022ff38bbf5e0531"),
    "name" : "choco",
    "parent" : ObjectId("54de8b9f022ff38bbf5e0530")
},
{
    "_id" : ObjectId("54de8bc8022ff38bbf5e0532"),
    "name" : "apple",
    "parent" : ObjectId("54de8b9f022ff38bbf5e0530")
}

我得到這個結果:

{
    "result" : [ 
        {
            "mainCategory" : {
                "_id" : ObjectId("54de8b9f022ff38bbf5e0530"),
                "name" : "Fridge"
            },
            "subCategories" : [ 
                {
                    "_id" : ObjectId("54de8bc8022ff38bbf5e0532"),
                    "name" : "apple"
                }, 
                {
                    "_id" : ObjectId("54de8bba022ff38bbf5e0531"),
                    "name" : "choco"
                }
            ]
        }
    ],
    "ok" : 1
}

至於異步,通常您會執行以下操作:

db.collection.aggregate(thePipeLineAbove, function(err, results) {

    // handle err
    if (err) {
       // deal with it
    } else {
        console.log(results);
    }
});

但這取決於您的MongoDB驅動程序。

即使您具有更深的層次結構,也可以擴展它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM