node.js - 使用 mongodb 和 nodejs 的类别层次聚合

标签 node.js mongodb hierarchy

我的文档结构如下:

{
    "_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。

我将如何为此进行异步调用?

最佳答案

您想要冰箱和所有子类别吗?

异步也是一个问题吗?

我想你可以在这里使用聚合。

假设您正在寻找一个带有 _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 驱动程序。

即使你有更深的层次结构,你也可以扩展它。

关于node.js - 使用 mongodb 和 nodejs 的类别层次聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28492117/

相关文章:

node.js - npm update -package- 不更新包

MongoDB - 根据另一个数组过滤一个数组

javascript - 在 javascript/node.js 中重现 MongoDB 的映射/发出功能(不使用 MongoDB)

grails - 在 grails 域类上使用泛型时出错

python - 导入错误。循环引用

node.js - 如何访问 mongoose.js 中的 oplog?

node.js - 错误: FAILED_PRECONDITION: no matching index found.推荐索引为:

c - 使用 tcp_nodelay 发送大消息时出现奇怪的延迟

mongodb - MongoDB是否以某种方式仅限于单核?

Angular 2 - ng-bootstrap 如何为他们的 NgbRadio 指令提供 NgbRadioGroup 和 NgbButtonLabel?