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 @@ -179,6 +179,7 @@ public function getFresh($columns = [])
179
179
// Use MongoDB's aggregation framework when using grouping or aggregation functions.
180
180
if ($ this ->groups or $ this ->aggregate or $ this ->paginating ) {
181
181
$ group = [];
182
+ $ unwinds = [];
182
183
183
184
// Add grouping columns to the $group part of the aggregation pipeline.
184
185
if ($ this ->groups ) {
@@ -204,6 +205,13 @@ public function getFresh($columns = [])
204
205
$ function = $ this ->aggregate ['function ' ];
205
206
206
207
foreach ($ this ->aggregate ['columns ' ] as $ column ) {
208
+ // Add unwind if a subdocument array should be aggregated
209
+ // column: subarray.price => {$unwind: '$subarray'}
210
+ if (count ($ splitColumns = explode ('.*. ' , $ column )) == 2 ) {
211
+ $ unwinds [] = $ splitColumns [0 ];
212
+ $ column = implode ('. ' , $ splitColumns );
213
+ }
214
+
207
215
// Translate count into sum.
208
216
if ($ function == 'count ' ) {
209
217
$ group ['aggregate ' ] = ['$sum ' => 1 ];
@@ -233,6 +241,12 @@ public function getFresh($columns = [])
233
241
if ($ wheres ) {
234
242
$ pipeline [] = ['$match ' => $ wheres ];
235
243
}
244
+
245
+ // apply unwinds for subdocument array aggregation
246
+ foreach ($ unwinds as $ unwind ){
247
+ $ pipeline [] = ['$unwind ' => '$ ' . $ unwind ];
248
+ }
249
+
236
250
if ($ group ) {
237
251
$ pipeline [] = ['$group ' => $ group ];
238
252
}
Original file line number Diff line number Diff line change @@ -420,6 +420,22 @@ public function testSubdocumentAggregate()
420
420
$ this ->assertEquals (16.25 , DB ::collection ('items ' )->avg ('amount.hidden ' ));
421
421
}
422
422
423
+ public function testSubdocumentArrayAggregate ()
424
+ {
425
+ DB ::collection ('items ' )->insert ([
426
+ ['name ' => 'knife ' , 'amount ' => [['hidden ' => 10 , 'found ' => 3 ]]],
427
+ ['name ' => 'fork ' , 'amount ' => [['hidden ' => 35 , 'found ' => 12 ]]],
428
+ ['name ' => 'spoon ' , 'amount ' => [['hidden ' => 14 , 'found ' => 21 ]]],
429
+ ['name ' => 'spoon ' , 'amount ' => [['hidden ' => 6 , 'found ' => 4 ]]],
430
+ ]);
431
+
432
+ $ this ->assertEquals (65 , DB ::collection ('items ' )->sum ('amount.*.hidden ' ));
433
+ $ this ->assertEquals (4 , DB ::collection ('items ' )->count ('amount.*.hidden ' ));
434
+ $ this ->assertEquals (6 , DB ::collection ('items ' )->min ('amount.*.hidden ' ));
435
+ $ this ->assertEquals (35 , DB ::collection ('items ' )->max ('amount.*.hidden ' ));
436
+ $ this ->assertEquals (16.25 , DB ::collection ('items ' )->avg ('amount.*.hidden ' ));
437
+ }
438
+
423
439
public function testUpsert ()
424
440
{
425
441
DB ::collection ('items ' )->where ('name ' , 'knife ' )
You can’t perform that action at this time.
0 commit comments