如何在NodeJS Sequelize中按查询计数组

And*_*Ray 18 postgresql node.js sequelize.js

在Rails中,我可以对模型的Likes数量执行简单的ORM查询:

    @records = Model
        .select( 'model.*' )
        .select( 'count(likes.*) as likes_count' )
        .joins( 'LEFT JOIN likes ON model.id = likes.model_id' )
        .group( 'model.id' )
Run Code Online (Sandbox Code Playgroud)

这会生成查询:

SELECT  models.*, count(likes.*) as likes_count
FROM "models" JOIN likes ON models.id = likes.model_id
GROUP BY models.id
Run Code Online (Sandbox Code Playgroud)

在Node Sequelize中,任何尝试类似操作的尝试都会失败:

return Model.findAll({
    group: [ '"Model".id' ],
    attributes: ['id', [Sequelize.fn('count', Sequelize.col('"Likes".id')), 'likes_count']],
    include: [{ attributes: [], model: Like }],
});
Run Code Online (Sandbox Code Playgroud)

这会生成查询:

SELECT
    Model.id,
    count(Likes.id) AS likes_count,
    Likes.id AS Likes.id           # Bad!
FROM Models AS Model
LEFT OUTER JOIN Likes
    AS Likes
    ON Model.id = Likes.model_id
GROUP BY Model.id;
Run Code Online (Sandbox Code Playgroud)

这会产生错误:

column "Likes.id" must appear in the GROUP BY clause or be used in an aggregate function
Run Code Online (Sandbox Code Playgroud)

它错误地选择了likes.id,我不知道为什么,也不知道如何摆脱它.

НЛО*_*НЛО 18

这个续集的github问题看起来完全像你的情况:

User.findAll({
  attributes: ['User.*', 'Post.*', [sequelize.fn('COUNT', 'Post.id'), 'PostCount']],
  include: [Post]
});
Run Code Online (Sandbox Code Playgroud)


小智 7

要解决这个问题,我们需要升级到sequelize的最新版本并包含raw = true,这是我在经过大量迭代和偏离google搜索后的工作方式.

 getUserProjectCount: function (req, res) {
        Project.findAll(
            {
                attributes: ['User.username', [sequelize.fn('COUNT', sequelize.col('Project.id')), 'ProjectCount']],
                include: [
                    {
                        model: User,
                        attributes: [],
                        include: []
                    }
                ],
                group: ['User.username'],
                raw:true
            }
        ).then(function (projects) {
            res.send(projects);
        });
    }
Run Code Online (Sandbox Code Playgroud)

我的参考模型在哪里

//user
var User = sequelize.define("User", {
    username: Sequelize.STRING,
    password: Sequelize.STRING
});

//project
var Project = sequelize.define("Project", {
    name: Sequelize.STRING,
    UserId:{
         type:Sequelize.INTEGER,
         references: {
                 model: User,
                  key: "id"
         }
    }
});

Project.belongsTo(User);
User.hasMany(Project);
Run Code Online (Sandbox Code Playgroud)

迁移后,ORM在我的postgres服务器中创建"用户"和"项目"表.这是ORM的SQL查询

SELECT 
  "User"."username", COUNT("Project"."id") AS "ProjectCount" 
 FROM 
    "Projects" AS "Project" 
    LEFT OUTER JOIN "Users" AS "User" ON "Project"."UserId" = "User"."id" 
 GROUP BY 
   "User"."username";
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是一个很好的例子,为什么要不惜一切代价避免使用Sequelize.它不仅仅是对SQL的漏洞抽象,他们发明了自己的无意义抽象来修复自己的软件,比如"raw":true`.SQL已经是一个很好的抽象,Sequelize只会在它上面引入新的bug. (7认同)
  • @AndyRay您可以为节点推荐更好的ORM吗?(使用纯数据库驱动程序(例如,sqlite)需要样板提示音) (2认同)