web-dev-qa-db-fra.com

Comment compter un groupe par requête dans NodeJS Sequelize

Dans Rails je peux effectuer une simple requête ORM pour le nombre de Likes d'un modèle:

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

Cela génère la requête:

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

Dans Node Sequelize, toute tentative de faire quelque chose de similaire échoue:

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

Cela génère la requête:

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;

Ce qui génère l'erreur:

column "Likes.id" must appear in the GROUP BY clause or be used in an aggregate function

C'est sélectionner par erreur likes.id, et je n'ai aucune idée pourquoi, ni comment s'en débarrasser.

18
Andy Ray

Ce problème de github séquentiel ressemble totalement à votre cas:

User.findAll({
  attributes: ['User.*', 'Post.*', [sequelize.fn('COUNT', 'Post.id'), 'PostCount']],
  include: [Post]
});
19
НЛО

Pour résoudre ce problème, nous devons mettre à niveau vers la dernière version de sequelize et inclure raw = true, voici comment je l'avais fait après beaucoup d'itérations et de googler hors cours.

 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);
        });
    }

où sont mes modèles de référence

//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);

après la migration, ORM crée une table "Utilisateurs" et "Projets" dans mon serveur postgres. Voici SQL Query par ORM

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";
8
sangram