Search code examples
node.jsmongodbgroup-bypipelineaggregation

MongoDB group by aggregation query


The data I have is:

[
    { type: 'software' },
    { type: 'hardware' },
    { type: 'software' },
    { type: 'network' },
    { type: 'test' },
    ...
]

I want to create a MongoDB group by aggregation pipeline to return the data like this: I only want 3 objects in result the third object in result {_id: 'other', count: 2}, This should be the sum of counts of type other that software and hardware

[
    {_id: 'software', count: 2},
    {_id: 'hardware', count: 1},
    {_id: 'other', count: 2},
]

Solution

  • This is the exact query (MongoPlayground) that you need if those data are separate documents. Just add $project stage before group and then $switch operator. (If those field data are number, you might wanna check $bucket

    db.collection.aggregate([
      {
        "$project": {
          type: {
            "$switch": {
              "branches": [
                {
                  "case": {
                    "$eq": [
                      "$type",
                      "software"
                    ]
                  },
                  "then": "software"
                },
                {
                  "case": {
                    "$eq": [
                      "$type",
                      "hardware"
                    ]
                  },
                  "then": "hardware"
                }
              ],
              default: "other"
            }
          }
        }
      },
      {
        "$group": {
          "_id": "$type",
          "count": {
            "$sum": 1
          }
        }
      }
    ])
    

    Also, I'd like to recommend avoiding field name type. Actually it doesn't reserve in MongoDB, but however it could bring conflicts with some drivers since, in schema/model files, type fields are referred to the exact BSON type of the field.