Search code examples
mongodblaravelmongodb-queryjenssegers-mongodb

MongoDB aggregate + $match + $group + Condition filter


Here is my code :

$profiles = Profile::raw()->aggregate([
            [
                '$unwind' => '$channels'
            ],
            [
                '$match' => [
                    'channels.sign_up' => true,
                ]
            ],
            [
                '$match' => [
                    "city_id" => request()->input('city_id'),
                ]
            ],
            [
                '$match' => [
                    'created_at' => [
                        '$gte' => request('start_date', date('Y-m-d') . ' 00:00:00'),
                        '$lte' => request('end_date', date('Y-m-d') . ' 23:59:59'),
                    ]
                ]
            ],
            [
                '$group' => [
                    '_id' => '$channels.slug',
                    'user_count' => ['$sum' => 1]
                ]
            ],
            [
                '$sort' => [
                    "user_count" => -1
                ]
            ]
        ]);

where 2nd and 3rd '$match' is optional based on filter. if city_id is not empty than i have to add 2nd '$match' and if start_date and end_date is not empty than i have to add 3rd '$match'.

I am using jenssegers/laravel-mongodb.

Need suggestion :)


Solution

  • You can use $and condition.

    Please check below code that help you.

    var matchConditionsArray = [];
    matchConditionsArray.push({ 'channels.sign_up': true });
    
    if (request.city_id) {
      matchConditionsArray.push({ 'city_id': request.city_id });
    }
    
    if (request.start_date && request.end_date) {
      matchConditionsArray.push({ "created_at": { $gte: request.start_date } }, { "created_at": { $lte: request.end_date } });
    }
    
    aggregate([
      {
        $match: {
          $and: matchConditionsArray
        }
      },
      ....
    ]