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

  1. Remove orderBy on the aggregate alias and sort in PHP with ->get()->sortBy('posts_count') (or sortByDesc).
  2. Compute the aggregate first and sort the resulting collection: Model::withCount('posts')->get()->sortByDesc('posts_count')->values().
  3. 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

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


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)