Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add empty buckets in mongo aggregation

I have the following aggregation:

const buckets = await StatisticModel.aggregate([
  {
    $bucket: {
      groupBy: '$ranking',
      boundaries: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11],
    },
  },
])

Which returns the following object:

[
  { _id: 3, count: 6  },
  { _id: 4, count: 98 },
  { _id: 5, count: 81 },
  { _id: 6, count: 25 },
  { _id: 7, count: 4 }
]

How can I add the missing (empty) buckets?

This is a simple example but I have more complexe ones where I generate the boundaries and I want to return to the front-end all the buckets and not only the filled ones.

like image 397
Kerumen Avatar asked Sep 06 '25 05:09

Kerumen


1 Answers

You can use below aggregation

db.collection.aggregate([
  { "$facet": {
    "data": [
      { "$bucket": {
        "groupBy": "$ranking",
        "boundaries": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
      }}
    ]
  }},
  { "$addFields": {
    "data": {
      "$map": {
        "input": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11],
        "as": "i",
        "in": {
          "_id": "$$i",
          "count": {
            "$cond": [
              { "$eq": [{ "$indexOfArray": ["$data._id", "$$i"] }, -1] },
              0,
              { "$arrayElemAt": ["$data.count", { "$indexOfArray": ["$data._id", "$$i"] }] }
            ]
          }
        }
      }
    }
  }},
  { "$unwind": "$data" },
  { "$replaceRoot": { "newRoot": "$data" }}
])

But better to do with javascript

const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
const array2 = [
  { "_id": 3, "count": 6 },
  { "_id": 4, "count": 98 },
  { "_id": 5, "count": 81 },
  { "_id": 6, "count": 25 },
  { "_id": 7, "count": 4 }
]

array.map((ar) => {
  const index = array2.map((e) => { return e._id }).indexOf(ar)
  if (index === -1) {
    array2.push({ _id: ar, count: 0 })
  }
})

console.log(array2)
like image 168
Ashh Avatar answered Sep 07 '25 20:09

Ashh