mongodb match and group 2 query in one

Viewed 42
var oneWeekAgo = new Date();
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);  



  User.aggregate([
            { $match: { isAdmin: false, isActive: true } },
            {
                $group: {
                    _id: null,
                    totalCount: {
                        $sum: 1
                    }
                }
            },
        ])


  User.aggregate([
                { $match: { isAdmin: false, dateCreated: { $gte: oneWeekAgo }, isActive: true } },
                {
                    $group: {
                        _id: null,
                        lastWeekTotal: {
                            $sum: 1
                        }
                    }
                },
            ])

is there a way to combine 2 aggregation queries above?

I want to count all the entries in the collection and also entries that are created within a week. Expected result:

[ { _id: null, totalCount: 100 , lastWeekTotal: 10 } ] 
1 Answers

You can combine inside $group together like this,

  • The $cond operator, there are three arguments ($cond: [if check condition, then, else])
  • first part if condition checks your conditions using $and operator, if conditions is true then return 1 otherwise 0
User.aggregate([
  {
    $group: {
      _id: null,
      totalCount: {
        $sum: {
          $cond: [
            {
              $and: [
                { $eq: ["$isAdmin", false] },
                { $eq: ["$isActive", true] }
              ]
            },
            1,
            0
          ]
        }
      },
      lastWeekTotal: {
        $sum: {
          $cond: [
            {
              $and: [
                { $gte: ["$dateCreated", oneWeekAgo] },
                { $eq: ["$isAdmin", false] },
                { $eq: ["$isActive", true] }
              ]
            },
            1,
            0
          ]
        }
      }
    }
  }
])

Playground

Related