Skip to content

Commit 75130aa

Browse files
authored
Skip empty $match from pipeline builder (#2740)
1 parent b545c21 commit 75130aa

File tree

4 files changed

+32
-10
lines changed

4 files changed

+32
-10
lines changed

lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use stdClass;
1818
use TypeError;
1919

20-
use function array_map;
2120
use function array_unshift;
2221
use function func_get_arg;
2322
use function func_num_args;
@@ -295,10 +294,15 @@ public function getPipeline(/* bool $applyFilters = true */): array
295294
));
296295
}
297296

298-
$pipeline = array_map(
299-
static fn (Stage $stage) => $stage->getExpression(),
300-
$this->stages,
301-
);
297+
$pipeline = [];
298+
foreach ($this->stages as $stage) {
299+
$stage = $stage->getExpression();
300+
if ($stage === null) {
301+
continue;
302+
}
303+
304+
$pipeline[] = $stage;
305+
}
302306

303307
if ($this->getStage(0) instanceof Stage\IndexStats) {
304308
// Don't apply any filters when using an IndexStats stage: since it

lib/Doctrine/ODM/MongoDB/Aggregation/Stage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function __construct(Builder $builder)
3333
* @return array<string, mixed>
3434
* @phpstan-return StageExpression
3535
*/
36-
abstract public function getExpression(): array;
36+
abstract public function getExpression(): ?array;
3737

3838
/**
3939
* Executes the aggregation pipeline

lib/Doctrine/ODM/MongoDB/Aggregation/Stage/MatchStage.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,15 @@ public function geoWithinPolygon($point1, $point2, $point3, ...$points): static
279279
return $this;
280280
}
281281

282-
public function getExpression(): array
282+
public function getExpression(): ?array
283283
{
284-
return [
285-
'$match' => $this->query->getQuery() ?: (object) [],
286-
];
284+
$query = $this->query->getQuery();
285+
286+
if (! $query) {
287+
return null;
288+
}
289+
290+
return ['$match' => $query];
287291
}
288292

289293
/**

tests/Doctrine/ODM/MongoDB/Tests/Aggregation/BuilderTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,20 @@ public function testBuilderWithIndexStatsStageDoesNotApplyFilters(): void
450450
self::assertSame('$indexStats', array_keys($builder->getPipeline()[0])[0]);
451451
}
452452

453+
public function testEmptyMatchStageIsSkipped(): void
454+
{
455+
$builder = $this->dm
456+
->createAggregationBuilder(BlogPost::class)
457+
->match()->field('foo')->equals('bar')
458+
->match()
459+
->match()->field('baz')->equals('qux');
460+
461+
self::assertSame([
462+
['$match' => ['foo' => 'bar']],
463+
['$match' => ['baz' => 'qux']],
464+
], $builder->getPipeline());
465+
}
466+
453467
public function testNonRewindableBuilder(): void
454468
{
455469
$builder = $this->dm

0 commit comments

Comments
 (0)