0

I have a collection of Items with multiple documents stored in MongoDB. The structure is as follows:

{ id: 1, colour: red },
{ id: 2, colour: blue},
{ id: 3, colour: red },
{ id: 4, colour: green},
{ id: 5, colour: green}

I would like to count how many items are in the DB by colour. The result should be like this:

colour blue: 1
colour red: 2
colour green: 2

I would like to avoid the following two approaches since the records could be a really large number and as I can imagine, these would be inefficient and costly.

const items = await Item.find({ colour: {$in: ['red', 'blue', 'green']} });
items.forEach(item => {
  // do the counting here
});

NEITHER

const blue = await Item.find({ colour: blue }).count();
const red = await Item.find({ colour: red }).count();
const green = await Item.find({ colour: green }).count();

The closest I found to my problem is this.

What is the best way to obtain these numbers?

Thanks for the help!!

enNa
  • 15
  • 5
  • 1
    check out this question, I think it's similar to your https://stackoverflow.com/questions/28013318/mongo-count-occurrences-of-each-value-for-a-set-of-documents – shadi1999 Aug 29 '22 at 18:25
  • @shadi1999 thank you very much! I think this is my answer! – enNa Aug 29 '22 at 19:06

1 Answers1

0

This was apparently quite easy using aggregation, doing like the following:

const result = await Item.aggregate().group({ _id: '$colour', count: { $sum: 1 }});

Or equivalent:

const result = await Item.aggregate([{ $group: { _id: '$colour', count: { $sum: 1 }} }]);

The above would result:

[
  { "_id": "blue", "count": 1 },
  { "_id": "red", "count": 2 },
  { "_id": "green", "count": 2 }
]

Basically what the above code does, is to create an object with the properties _id and count. In the group operator, we pass the value of the _id which is the property to query and match the desired documents. The result is an array of these objects.

enNa
  • 15
  • 5