MongoDB 列出父类别中的子类别

标签 mongodb mongoose

所以我有下一个架构:

const CategorySchema = new Schema({
    name: {
        type: String,
        required: true,
    },
    parent: {
        type: Schema.Types.ObjectId,
        ref: 'Category',
        default: null,
    },
    order: {
        type: Number,
        required: true,
        min: 0,
    }
});

所以我想要的是获得下一个输出(为了简单起见,我放置了简单的_ids):

[
    {
        _id: '1',
        name: 'MainCategory1',
        parent: null,
        order: 0,
        children: [
            {
                _id: '3',
                name: 'SubCategory3',
                parent: '1',
                order: 0,
            },
        ]
    },
    {
        _id: '2',
        name: 'MainCategory2',
        parent: null,
        order: 1,
        children: [
            {
                _id: '4',
                name: 'SubCategory1',
                parent: '2',
                order: 0,
            },
            {
                _id: '5',
                name: 'SubCategory2',
                parent: '2',
                order: 1,
            },
        ]
    },
]

那么我怎样才能得到这个结果呢?请注意,对于 parent 和 child 来说,它必须按“顺序”字段排序。

此外,是否可以使用 Mongoose 查询而不是聚合来获取此结果?

我知道如果我在架构中存储“子”数组而不是“父”数组,这可能会更简单,但我更喜欢这种方法,因为每个类别只有一个父级引用,并且文档不会因数组而变得臃肿objectid 的。换句话说,“children”数组可能非常巨大,而且我认为 mongo 如果在搜索时查看一个“parent”值,而不是查看“children”数组(可能有 100 多个 ObjectId 元素),那么它的工作速度会更快。

最佳答案

此处无法使用常规 .find(),但您可以利用聚合框架的 $graphLookup :

let Category = mongoose.model('Category', CategorySchema);

let result = await Category.aggregate([
    {
        $sort: { order: 1 }
    },
    {
        $graphLookup: {
            from: 'categories',
            startWith: '$_id',
            connectFromField: '_id',
            connectToField: 'parent',
            as: 'children'
        }
    },
    {
        $match: {
            parent: null
        }
    }
]);

关于MongoDB 列出父类别中的子类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60030113/

相关文章:

node.js - 无法处理model.save错误并返回到FE

node.js - Mongoose:获取最新记录,然后按另一个字段对它们进行排序

node.js - Mongoose :父级的预保存钩子(Hook)是否总是在嵌入文档的预保存钩子(Hook)之前执行?

mysql - mongodb性能相关参数

javascript - mocha测试中的Mongodb访问

java - 查询 MongoDB 最有效的方法是什么?

node.js - 在两个 Node 应用程序之间共享 session

node.js - 在预验证中间件之后创建或更新字段?

arrays - mongoDB 对嵌套对象数组的聚合查找

node.js - 嵌套文档中字段上的 Mongoose 索引