Mongoose and how to group by count

Pere Sola - May 22 '22 - - Dev Community

It may be an unpopular opinion but I don't like Mongoosejs docs - I think they take a lot of knowledge for granted and their code samples are poor. But maybe it's me :shrugs:

Anyway, I have a collection of documents that looks like:

[
     {
     _id: 1,
     category: food,
     name: avocado
     },
     {
     _id: 2,
     category: food,
     name: orange
     },
     {
     _id: 3,
     category: drink,
     name: milk
     },
]
Enter fullscreen mode Exit fullscreen mode

I wanted to create an endpoint that returns data like:
g

data: {
     food: 2,
     drink: 1
}

Enter fullscreen mode Exit fullscreen mode

Basically the name of the category and the count of documents. Well, that brought me on a journey that span a couple of tutorials and some other SO thread.

Disclaimer: I should probably be more familiar with MongoDB. I used to be, but like many things in life, you forget them and I am not ready to ramp up with MongoDB again and also with Mongoose, again. I just went straight to Mongoose.

First, I discovered grouping with Mongoose is called Aggregate. I found Model.aggregate(), which brought me to this tutorial. Their The $group Stage section gave me a solution that worked for me:

const data = await YourModelName.aggregate([
  {
    $group: {
      _id: '$category',
      count: { $sum: 1 } // this means that the count will increment by 1
    }
  }
]);
Enter fullscreen mode Exit fullscreen mode

But data was returned slightly different, not a big deal:

data: [
     {
     _id: "food",
     count: 2
     },
     {
     _id: "drink",
     count: 1
     }
]
Enter fullscreen mode Exit fullscreen mode

Not a big deal and probably as good as it gets, but I continued exploring. This brought me to a number of SO threads (there were not that many), slightly different topic but it revolved to more or less the same syntax.

And then, by chance, I discovered aggregate.sortByCount() here, which does the same out of the box!

const data = await Machine.aggregate().sortByCount("category");
Enter fullscreen mode Exit fullscreen mode

sortByCount expects the name of the field and it does the whole $group, $count, etc for you. Or at least this is what happened for me. Much more straightforward.

I think this is good enough for me for now, I will stop exploring this topic, hope this was useful for you (:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .