File tree Expand file tree Collapse file tree 2 files changed +30
-0
lines changed
src/Jenssegers/Mongodb/Query Expand file tree Collapse file tree 2 files changed +30
-0
lines changed Original file line number Diff line number Diff line change @@ -187,6 +187,7 @@ public function getFresh($columns = [])
187
187
// Use MongoDB's aggregation framework when using grouping or aggregation functions.
188
188
if ($ this ->groups or $ this ->aggregate or $ this ->paginating ) {
189
189
$ group = [];
190
+ $ unwinds = [];
190
191
191
192
// Add grouping columns to the $group part of the aggregation pipeline.
192
193
if ($ this ->groups ) {
@@ -212,6 +213,13 @@ public function getFresh($columns = [])
212
213
$ function = $ this ->aggregate ['function ' ];
213
214
214
215
foreach ($ this ->aggregate ['columns ' ] as $ column ) {
216
+ // Add unwind if a subdocument array should be aggregated
217
+ // column: subarray.price => {$unwind: '$subarray'}
218
+ if (count ($ splitColumns = explode ('.*. ' , $ column )) == 2 ) {
219
+ $ unwinds [] = $ splitColumns [0 ];
220
+ $ column = implode ('. ' , $ splitColumns );
221
+ }
222
+
215
223
// Translate count into sum.
216
224
if ($ function == 'count ' ) {
217
225
$ group ['aggregate ' ] = ['$sum ' => 1 ];
@@ -241,6 +249,12 @@ public function getFresh($columns = [])
241
249
if ($ wheres ) {
242
250
$ pipeline [] = ['$match ' => $ wheres ];
243
251
}
252
+
253
+ // apply unwinds for subdocument array aggregation
254
+ foreach ($ unwinds as $ unwind ){
255
+ $ pipeline [] = ['$unwind ' => '$ ' . $ unwind ];
256
+ }
257
+
244
258
if ($ group ) {
245
259
$ pipeline [] = ['$group ' => $ group ];
246
260
}
Original file line number Diff line number Diff line change @@ -419,6 +419,22 @@ public function testSubdocumentAggregate()
419
419
$ this ->assertEquals (16.25 , DB ::collection ('items ' )->avg ('amount.hidden ' ));
420
420
}
421
421
422
+ public function testSubdocumentArrayAggregate ()
423
+ {
424
+ DB ::collection ('items ' )->insert ([
425
+ ['name ' => 'knife ' , 'amount ' => [['hidden ' => 10 , 'found ' => 3 ]]],
426
+ ['name ' => 'fork ' , 'amount ' => [['hidden ' => 35 , 'found ' => 12 ]]],
427
+ ['name ' => 'spoon ' , 'amount ' => [['hidden ' => 14 , 'found ' => 21 ]]],
428
+ ['name ' => 'spoon ' , 'amount ' => [['hidden ' => 6 , 'found ' => 4 ]]],
429
+ ]);
430
+
431
+ $ this ->assertEquals (65 , DB ::collection ('items ' )->sum ('amount.*.hidden ' ));
432
+ $ this ->assertEquals (4 , DB ::collection ('items ' )->count ('amount.*.hidden ' ));
433
+ $ this ->assertEquals (6 , DB ::collection ('items ' )->min ('amount.*.hidden ' ));
434
+ $ this ->assertEquals (35 , DB ::collection ('items ' )->max ('amount.*.hidden ' ));
435
+ $ this ->assertEquals (16.25 , DB ::collection ('items ' )->avg ('amount.*.hidden ' ));
436
+ }
437
+
422
438
public function testUpsert ()
423
439
{
424
440
DB ::collection ('items ' )->where ('name ' , 'knife ' )
You can’t perform that action at this time.
0 commit comments