如何在Sequelize中返回树节点的子节点数?

时间:2014-07-20 18:15:42

标签: mysql sql node.js sequelize.js

我有一个像这样定义的分层树数据结构:

module.exports = function(sequelize, DataTypes) {
    var Category = sequelize.define('Category', {
            id: { type: DataTypes.STRING, primaryKey: true },
            parent: DataTypes.STRING,
            text: DataTypes.STRING
        }
    );
    Category.belongsTo(Category, { foreignKey: 'parent' });
    return Category;
};

我有一个服务返回给定节点的子节点列表,如下所示:

exports.categoryChildren = function(req, res) {
    var id = req.params.id;
    db.Category.findAll({ where: { parent: id }}).success(function(categories){
        return res.jsonp(categories);
    }).error(function(err){
        return res.render('error', { error: err, status: 500 });
    });
};

有没有办法让Sequelize为给定节点的每个孩子(即给定节点的孙子)返回孙子孙的数量?

我使用的SQL查询如下所示:

SELECT *, (select count(*) from Categories chld where chld.parent = cat.id) 
FROM `Categories` cat 
WHERE cat.`parent`='my_node_id';

但是,我找不到强制Sequelize生成类似查询的方法。

3 个答案:

答案 0 :(得分:1)

我最终使用了两个嵌套查询,如下所示。

优点:我保持在ORM范例内。

缺点:明显的性能影响。

exports.categoryChildren = function(req, res) {
    var id = req.params.id;

    db.Category.findAll({ where: { parent: id }}).success(function(categories) {
        var categoryIds = [];
        _.each(categories, function(element, index, list) {
            categoryIds[element.id] = element;
        });
        db.Category.findAll({attributes: [['Categories.parent', 'parent'], [Sequelize.fn('count', 'Categories.id'), 'cnt']], where: { parent: { in: _.keys(categoryIds) }}, group: ['Categories.parent']}).success(function(counts) {
            _.each(counts, function(element, index, list) {
                categoryIds[element.dataValues.parent].dataValues.cnt = element.dataValues.cnt;
            });
            return res.jsonp(categories);
        }).error(function(err){
            return res.render('error', {
                error: err,
                status: 500
            });
        });
    }).error(function(err){
        return res.render('error', {
            error: err,
            status: 500
        });
    });
};

答案 1 :(得分:0)

我遇到了同样的问题。到目前为止,我唯一能做的就是使用原始查询。

只有ORM不能做的事情,我认为这可能是其中之一。您可以使用query()

sequelize.query('select * from all_counts').success(function(counts) {...})

答案 2 :(得分:0)

只是没有使用ORM来计算那种东西。这是性能灾难。

使用数据库查询(如您指定的SQL)并定义该SQL的视图,并使用模型处理该视图。