findAndCountAll with `GROUP BY` clause causes count to be an array of objects

See original GitHub issue

What you are doing?

I’m trying to get the number of rows returned in using findAndCountAll with a GROUP BY clause however, instead of a single integer, I get an array of { count: x } objects.

const attributes = ['feed_id', [this.store.fn('COUNT', this.store.col('feed_id')), 'count']];
const where = { createdAt: { $gte: start, $lte: end } };
const group = ['feed_id'];
const order = [['count', 'DESC']];
const query = { where, attributes, order, group };

model.findAndCountAll(query).then(data => {
  console.log(data.count);
  console.log(data.rows);
});

What do you expect to happen?

I expected a single integer in count and an array of objects in row.

What is actually happening?

{
  count: [
    { count: '11' },
    { count: '20' },
    { count: '17' },
    { count: '17' },
    { count: '11' },
    ...
    { count: '12' },
    { count: '10' },
    { count: '18' } ],
  rows: [{
    dataValues: [Object],
    _previousDataValues: [Object],
    _changed: {},
    '$modelOptions': [Object],
    '$options': [Object],
    hasPrimaryKeys: true,
    __eagerlyLoadedAssociations: [],
    isNewRecord: false
  }, ...]
}

I got an array of count objects.

For me, the workaround was to stop using findAndCountAll and make an explicit model.count transaction before the findAll. I then removed the GROUP BY clause and replaced the COUNT attribute with COUNT(DISTINCT field).

SELECT COUNT(feed_id) AS "count" FROM "history" AS "history" WHERE ("history"."created_at" >= '2016-04-22 07:24:26.038 +00:00' AND "history"."created_at" <= '2016-06-21 07:24:26.040 +00:00') GROUP BY "feed_id";
SELECT COUNT(DISTINCT feed_id) AS "count" FROM "history" AS "history" WHERE ("history"."created_at" >= '2016-04-22 07:24:26.038 +00:00' AND "history"."created_at" <= '2016-06-21 07:24:26.040 +00:00')

Is this something sequelize can do automatically when it sees a GROUP BY clause?

Dialect: postgres Database version: 9.5.2 Sequelize version: 3.23.0

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:13
  • Comments:34 (9 by maintainers)

github_iconTop GitHub Comments

44reactions
young-krcommented, Jan 18, 2018

just use “result.count.length” instead “result.count” when you use group by in findAndCountAll.

13reactions
davidvuongcommented, Jun 21, 2016

Thanks for getting back to me, @sushantdhiman however that isn’t exactly my problem. My problem is the value of count from findAndCountAll. If we use your example, and pass that into findAndCountAll, this would be the result we’d get:

{
  count: [
    { count: "..." },
    { count: "..." },
    { count: "..." },
    { count: "..." },
    ...
    { count: "..." },
  ],
  rows: [{
    ...
    dataValues: {
      count: "...",
      dept_id: "..."
    }
  }, ...]
}

The objects from rows isn’t the problem, it’s exactly what I expect it to be. The problem is with count. I expected that to be an integer representing the total number of rows. Looking at the source (https://github.com/sequelize/sequelize/blob/master/lib/model.js#L1653-L1665), it seems like count is expected to be integer too. However, it’s not. It’s an array of objects.

This kind of looks like a bug to me.

Read more comments on GitHub >

github_iconTop Results From Across the Web

orm - sequelize: how to do equivalent of findAndCountAll for ...
I had this problem earlier, and I decided to change functionality in this way... const include = [ { model: models.UserGroup, attributes: [] ......
Read more >
How to add GROUP BY clause to a Sequelize find method
In Sequelize, you can add the group option in your query method findAll() to add the GROUP BY clause to the generated SQL...
Read more >
Aggregation, grouping, and summarizing (Concepts) - Prisma
Aggregation, grouping, and summarizing. Prisma Client allows you to count records, aggregate number fields, and select distinct field values.
Read more >
Array.prototype.group() - JavaScript - MDN Web Docs - Mozilla
The returned object has separate properties for each group, containing arrays with the elements in the group.
Read more >
Mongoose v6.8.2: API docs
[options] «Object» passed down to the MongoDB driver's connect() function, ... Assume `Group` has a document array `users` const group = await Group....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found