aggregate = []; $aggregate[] = [ '$group' => [ '_id' => [ 'name' => '$name', ], ], ]; $results = $this->getCollection()->aggregate($aggregate);
This code will group our results by name field. Let’s try with many fields, it’s still very simple:
$aggregate[] = [ '$group' => [ '_id' => [ 'name' => '$name', 'user' => '$user', ], ], ];
Rest will will be the same as on standard find command but… as you can see, results will be different, because with grouping we don’t fetch all fields, but only grouping result (new _id). What can we do with this? Solution is simple, but may be a bit onerous – we must specify fields to fetch as other arguments:
aggregate = []; $aggregate[] = [ '$group' => [ '_id' => [ 'name' => '$name', 'user' => '$user', ], 'name' => ['$first' => '$name'], 'user' => ['$first' => '$user'], 'birthdate' => ['$first' => '$birthdate'], 'age' => ['$first' => '$age'], ], ];
This example will group records by name and user and fetch name, user, birthdate and age of them.
Aggregation caveats
aggregate = []; $aggregate[] = ['$limit' => $limit]; $aggregate[] = [ '$group' => [ '_id' => [ 'name' => '$name', ], 'name' => ['$first' => '$name'], 'user' => ['$first' => '$user'], ], ];
and similar example:
aggregate = []; $aggregate[] = [ '$group' => [ '_id' => [ 'name' => '$name', ], 'name' => ['$first' => '$name'], 'user' => ['$first' => '$user'], ], ]; $aggregate[] = ['$limit' => $limit];
Results will be completely different, because on first example we first limit records and then grouping – results will be „incorrect”, because we use only limited portion of data! Also, we must remember to sort our results BEFORE and after grouping if order of one field is import for us:
aggregate = []; $aggregate[] = ['$match' => $filters]; // Filter records $aggregate[] = ['$sort' => ['_sort_date' => -1]]; // Our sort date $aggregate[] = [ '$group' => [ '_id' => [ 'name' => '$name', ], 'name' => ['$first' => '$name'], 'user' => ['$first' => '$user'], ], ]; $aggregate[] = ['$sort' => ['_sort_date' => -1]]; // Second sort - after grouping $aggregate[] = ['$limit' => $limit]; // In the end, limit results