Skip to content

Commit ae2c8a0

Browse files
committed
Sort in the stage instead of using stage
1 parent 70900a5 commit ae2c8a0

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

src/Doctrine/Odm/Extension/OrderExtension.php

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use ApiPlatform\Doctrine\Odm\PropertyHelperTrait as MongoDbOdmPropertyHelperTrait;
1818
use ApiPlatform\Metadata\Operation;
1919
use Doctrine\ODM\MongoDB\Aggregation\Builder;
20+
use Doctrine\ODM\MongoDB\Aggregation\Stage\Search;
2021
use Doctrine\ODM\MongoDB\Aggregation\Stage\Sort;
2122
use Doctrine\Persistence\ManagerRegistry;
2223

@@ -66,7 +67,8 @@ public function applyToCollection(Builder $aggregationBuilder, string $resourceC
6667
if ($this->isPropertyNested($field, $resourceClass)) {
6768
[$field] = $this->addLookupsForNestedProperty($field, $aggregationBuilder, $resourceClass, true);
6869
}
69-
$aggregationBuilder->sort(
70+
$this->addSort(
71+
$aggregationBuilder,
7072
$context['mongodb_odm_sort_fields'] = ($context['mongodb_odm_sort_fields'] ?? []) + [$field => $order]
7173
);
7274
}
@@ -76,8 +78,9 @@ public function applyToCollection(Builder $aggregationBuilder, string $resourceC
7678

7779
if (null !== $this->order) {
7880
foreach ($identifiers as $identifier) {
79-
$aggregationBuilder->sort(
80-
$context['mongodb_odm_sort_fields'] = ($context['mongodb_odm_sort_fields'] ?? []) + [$identifier => $this->order]
81+
$this->addSort(
82+
$aggregationBuilder,
83+
$context['mongodb_odm_sort_fields'] = ($context['mongodb_odm_sort_fields'] ?? []) + [$identifier => $this->order],
8184
);
8285
}
8386
}
@@ -88,26 +91,30 @@ protected function getManagerRegistry(): ManagerRegistry
8891
return $this->managerRegistry;
8992
}
9093

91-
private function hasSortStage(Builder $aggregationBuilder): bool
94+
private function addSort(Builder $aggregationBuilder, array $sortFields): void
9295
{
93-
$shouldStop = false;
94-
$index = 0;
96+
$firstStage = $aggregationBuilder->getPipeline(0);
97+
if ($firstStage instanceof Search) {
98+
// The $search stage supports "sort" for performance, it's always first if present
99+
$firstStage->sort($sortFields);
100+
} else {
101+
// Append a $sort stage at the end of the pipeline
102+
$aggregationBuilder->sort($sortFields);
103+
}
104+
}
95105

96-
do {
97-
try {
106+
private function hasSortStage(Builder $aggregationBuilder): bool
107+
{
108+
try {
109+
for ($index = 0; true; $index++) {
98110
if ($aggregationBuilder->getStage($index) instanceof Sort) {
99111
// If at least one stage is sort, then it has sorting
100112
return true;
101113
}
102-
} catch (\OutOfRangeException $outOfRangeException) {
103-
// There is no more stages on the aggregation builder
104-
$shouldStop = true;
105114
}
106-
107-
++$index;
108-
} while (!$shouldStop);
109-
110-
// No stage was sort, and we iterated through all stages
111-
return false;
115+
} catch (\OutOfRangeException) {
116+
// There is no more stages on the aggregation builder
117+
return false;
118+
}
112119
}
113120
}

0 commit comments

Comments
 (0)