32
32
use MongoDB \Builder \Stage \ReplaceRootStage ;
33
33
use MongoDB \Builder \Stage \SkipStage ;
34
34
use MongoDB \Builder \Stage \SortStage ;
35
+ use MongoDB \Builder \Stage \UnwindStage ;
36
+ use MongoDB \Builder \Type \StageInterface ;
35
37
use MongoDB \Builder \Variable ;
36
38
use MongoDB \Driver \Cursor ;
37
39
use Override ;
@@ -292,13 +294,9 @@ public function dump(mixed ...$args)
292
294
}
293
295
294
296
/**
295
- * Return the MongoDB query to be run in the form of an element array like ['method' => [arguments]].
296
- *
297
- * Example: ['find' => [['name' => 'John Doe'], ['projection' => ['birthday' => 1]]]]
298
- *
299
- * @return array<string, mixed[]>
297
+ * @return StageInterface[]
300
298
*/
301
- public function toMql (): array
299
+ protected function getPipeline (): array
302
300
{
303
301
$ columns = $ this ->columns ?? [];
304
302
@@ -373,33 +371,33 @@ public function toMql(): array
373
371
// Build the aggregation pipeline.
374
372
$ pipeline = [];
375
373
if ($ wheres ) {
376
- $ pipeline [] = [ ' $match ' => $ wheres] ;
374
+ $ pipeline [] = new MatchStage (... $ wheres) ;
377
375
}
378
376
379
377
// apply unwinds for subdocument array aggregation
380
378
foreach ($ unwinds as $ unwind ) {
381
- $ pipeline [] = [ ' $unwind ' => ' $ ' . $ unwind] ;
379
+ $ pipeline [] = new UnwindStage ( $ unwind) ;
382
380
}
383
381
384
382
if ($ group ) {
385
- $ pipeline [] = [ ' $group ' => $ group] ;
383
+ $ pipeline [] = new GroupStage (... $ group) ;
386
384
}
387
385
388
386
// Apply order and limit
389
387
if ($ this ->orders ) {
390
- $ pipeline [] = [ ' $sort ' => $ this ->orders ] ;
388
+ $ pipeline [] = new SortStage ( $ this ->orders ) ;
391
389
}
392
390
393
391
if ($ this ->offset ) {
394
- $ pipeline [] = [ ' $skip ' => $ this ->offset ] ;
392
+ $ pipeline [] = new SkipStage ( $ this ->offset ) ;
395
393
}
396
394
397
395
if ($ this ->limit ) {
398
- $ pipeline [] = [ ' $limit ' => $ this ->limit ] ;
396
+ $ pipeline [] = new LimitStage ( $ this ->limit ) ;
399
397
}
400
398
401
399
if ($ this ->projections ) {
402
- $ pipeline [] = [ ' $project ' => $ this ->projections ] ;
400
+ $ pipeline [] = new ProjectStage (... $ this ->projections ) ;
403
401
}
404
402
405
403
$ options = [
@@ -457,6 +455,22 @@ public function toMql(): array
457
455
$ pipeline [] = new ProjectStage (...$ projection );
458
456
}
459
457
458
+ return $ pipeline ;
459
+ }
460
+
461
+ /**
462
+ * Return the MongoDB query to be run in the form of an element array like ['method' => [arguments]].
463
+ *
464
+ * Example: ['find' => [['name' => 'John Doe'], ['projection' => ['birthday' => 1]]]]
465
+ *
466
+ * @return array<string, mixed[]>
467
+ */
468
+ public function toMql (): array
469
+ {
470
+ $ pipeline = $ this ->getPipeline ();
471
+ $ encoder = new BuilderEncoder ();
472
+ $ pipeline = $ encoder ->encode (new Pipeline (...$ pipeline ));
473
+
460
474
$ options = ['typeMap ' => ['root ' => 'array ' , 'document ' => 'array ' ]];
461
475
462
476
if ($ this ->timeout ) {
@@ -468,12 +482,8 @@ public function toMql(): array
468
482
}
469
483
470
484
$ options = array_merge ($ options , $ this ->options );
471
-
472
485
$ options = $ this ->inheritConnectionOptions ($ options );
473
486
474
- $ encoder = new BuilderEncoder ();
475
- $ pipeline = $ encoder ->encode (new Pipeline (...$ pipeline ));
476
-
477
487
return ['aggregate ' => [$ pipeline , $ options ]];
478
488
}
479
489
@@ -554,9 +564,16 @@ public function generateCacheKey()
554
564
return md5 (serialize (array_values ($ key )));
555
565
}
556
566
557
- /** @inheritdoc */
558
- public function aggregate ($ function , $ columns = [])
567
+ /**
568
+ * @return self|PipelineBuilder
569
+ * @psalm-return $function === null ? PipelineBuilder : self
570
+ */
571
+ public function aggregate ($ function = null , $ columns = [])
559
572
{
573
+ if ($ function === null ) {
574
+ return new PipelineBuilder ($ this ->getPipeline ());
575
+ }
576
+
560
577
$ this ->aggregate = [
561
578
'function ' => $ function ,
562
579
'columns ' => $ columns ,
0 commit comments