2015-04-25 11 views
11

W Rails mogę wykonywać proste zapytanie ORM dla liczby lubi model:Jak policzyć grupy przez kwerendę w NodeJS Sequelize

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

ten generuje zapytanie:

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

w Węźle Sequelize każda próba zrobienia czegoś podobnego nie:

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

ten generuje zapytanie:

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; 

który generuje błąd:

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

To błędnie wybierając likes.id, i nie mam pojęcia dlaczego, ani jak się go pozbyć.

+0

Zawsze wybierając identyfikator połączonego modelu, jest to kolejność techniczna i nie można go wyłączyć. Spróbuj dodać likes.id do klauzuli grupowej. –

+2

Odpowiedź na to pytanie, która została usunięta przez mod, nie obejmuje Sequelize. Często generuje nieprawidłowy kod SQL, który powoduje zawieszenie zapytania (masz jedno zadanie). Kreator zapytań Knex jest znacznie lepszym narzędziem, które oferuje taką samą abstrakcję światła wokół sql, co robi szyny. Sql jest już dobrą abstrakcją, nie pozwól, aby Sequelize pogorszyło się dla ciebie. –

+0

@ andy-ray której wersji sequelize ...? – Satyajeet

Odpowiedz

8

This sequelize github issue wygląda zupełnie jak sprawy:

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

Aby rozwiązać ten problem musimy uaktualnić do najnowszej wersji sequelize i obejmują surowe = true, Oto jak zrobiłem po wielu iteracji i wyłączenia -Gourse googling.

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

gdzie moi modele referencyjne są

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

po migracji ORM tworzyć & stół 'projektami' 'użytkownicy' do mojego serwera PostgreSQL. Tutaj jest zapytanie SQL 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"; 
+3

Myślę, że jest to świetny przykład, dlaczego unikać używania Sequelize za wszelką cenę. To nie tylko nieszczelna abstrakcja w stosunku do SQL, wymyślają własne nonsensowne abstrakcje, aby naprawić własne oprogramowanie, takie jak "raw": true'. SQL jest już dobrą abstrakcją, Sequelize tylko wprowadza nowe błędy na wierzchu. –

+0

+1 dla podpowiedzi z "raw = true". Bez tego moja kolejna wersja (wersja 3.27.0) działała szaleńczo. prosty przykład 'model.findAll \t \t \t cechami: [ 'nazwa' sequelize.fn ('suma' sequelize.col ('wartość'))] \t \t \t grupy: [ 'Nazwa'] ' wygenerowana struktura zgrupowana według" name "(to jest ok), ale zamiast sumy (wartości) znajdowała się jakaś trzecia kolumna, absolutnie niezwiązana. – venca163