mongodb/laravel-mongodb · error · LogicException
Ordering by the aggregated field
Error message
Ordering by the aggregated field "%s" is not supported, as it is computed after the documents are read. Sort the results with the collection method "sortBy" instead.
What it means
Aggregated fields (e.g. posts_count from withCount) do not exist in the stored MongoDB documents; they are computed after the documents are read. MongoDB cannot sort by them server-side, so orderBy() on an aggregate alias throws this LogicException at eager-load time.
Solutions
- Remove orderBy on the aggregate alias and sort in PHP with ->get()->sortBy('posts_count') (or sortByDesc).
- Compute the aggregate first and sort the resulting collection: Model::withCount('posts')->get()->sortByDesc('posts_count')->values().
- If server-side ordering is essential, denormalize the count into a real field maintained on write, then orderBy that field.
Example fix
// before
User::withCount('posts')->orderByDesc('posts_count')->get();
// after
User::withCount('posts')->get()->sortByDesc('posts_count')->values(); Defensive patterns
Strategy: try-catch
Validate before calling
// Do not orderBy an aggregate alias; check before building the query
$alias = 'posts_count';
if (isset($query->orders[$alias])) {
throw new LogicException("Cannot order by computed aggregate {$alias}.");
} Type guard
function ordersOnAggregate(object $query, string $alias): bool {
return isset($query->getQuery()->orders[$alias]);
} Try / catch
try {
$users = User::withCount('posts')->orderByDesc('posts_count')->get();
} catch (\LogicException $e) {
$users = User::withCount('posts')->get()->sortByDesc('posts_count')->values();
} Prevention
- Never call orderBy with an aggregate alias on MongoDB models.
- Sort aggregated results in PHP with collection sortBy/sortByDesc.
- Denormalize frequently sorted counters into stored fields updated on write.
When it happens
Trigger: Calling Model::withCount('posts')->orderBy('posts_count')->get() (or orderByDesc) using the aggregate alias as the sort column.
Common situations: Developers porting SQL Eloquent code where orderBy('posts_count') works via a subquery select; in MongoDB the alias is computed client-side, so server-side sorting fails.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Constraints on the embedded relation
- The relation key of type
- Aggregating the hybrid relation
- is not supported for relation aggregates.
- Parent model must be a document model.
AI-assisted analysis of mongodb/laravel-mongodb@0634653039 (2026-09-15).
Data as JSON: /api/errors/6cf9efd65311d37f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Helpers/QueriesRelationshipAggregates.php:330
class_basename($relation),
));
}
private function getAggregateParentKey(Relation $relation): ?string
{
return match (true) {
$relation instanceof HasOneOrMany => $relation->getLocalKeyName(),
$relation instanceof BelongsTo => $relation->getForeignKeyName(),
$relation instanceof BelongsToMany => $relation->getParentKeyName(),
default => null,
};
}
/** The aggregated value does not exist in the documents, the server cannot use it. */
private function assertAggregateNotUsedInQuery(string $alias): void
{
if (isset($this->getQuery()->orders[$alias])) {
throw new LogicException(sprintf(
'Ordering by the aggregated field "%s" is not supported, as it is computed after the documents are read. Sort the results with the collection method "sortBy" instead.',
$alias,
));
}
}
}
View on GitHub (pinned to 0634653039)