mongodb/laravel-mongodb · error · BadMethodCallException

Distinct queries cannot be used for pagination. Use GroupBy…

Error message

Distinct queries cannot be used for pagination. Use GroupBy instead

What it means

paginate()/paginate count queries cannot be built for queries that use distinct() in the MongoDB builder, because Mongo has no direct equivalent for counting distinct documents cheaply. The library throws before running so you don't get an incorrect count.

Solutions

  1. Replace ->distinct($col) with ->groupBy($col) before paginating; group-by count queries are supported.
  2. Paginate the base query without distinct and deduplicate client-side after the page is fetched (if the count semantics allow).
  3. Precompute the distinct values with ->aggregate(['$group' => ['_id' => '$col']]) and paginate the resulting collection.
  4. If unique docs are guaranteed by the schema (e.g. unique index), simply drop the distinct() call.

Example fix

// before
$users = User::distinct('email')->paginate(20);
// after
$users = User::groupBy('email')->paginate(20);
Defensive patterns

Strategy: try-catch

Validate before calling

if ($query->distinct) {
    $query->groupBy($distinctColumn);
}

Prevention

When it happens

Trigger: Calling ->distinct('category')->paginate(15); Model::distinct(...)->paginate(...); ->distinct('x')->groupBy(...) combos still starting with distinct set; any pagination (or paginate count query) on a builder where $builder->distinct is truthy.

Common situations: Converting SQL code that relied on DISTINCT for pagination counts; faceted listing pages; devs wanting unique values per page.

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/791da0fbef90e0db. Report an issue: GitHub.

Appendix: source

Thrown at src/Query/Builder.php:1172

        return $this->performUpdate($query);
    }

    /**
     * @return static
     *
     * @inheritdoc
     */
    #[Override]
    public function newQuery()
    {
        return new static($this->connection, $this->grammar, $this->processor);
    }

    #[Override]
    public function runPaginationCountQuery($columns = ['*'])
    {
        if ($this->distinct) {
            throw new BadMethodCallException('Distinct queries cannot be used for pagination. Use GroupBy instead');
        }

        if ($this->groups || $this->havings) {
            $without = $this->unions ? ['orders', 'limit', 'offset'] : ['columns', 'orders', 'limit', 'offset'];

            $mql = $this->cloneWithout($without)
                ->cloneWithoutBindings($this->unions ? ['order'] : ['select', 'order'])
                ->toMql();

            // Adds the $count stage to the pipeline
            $mql['aggregate'][0][] = ['$count' => 'aggregate'];

            return $this->collection->aggregate($mql['aggregate'][0], $mql['aggregate'][1])->toArray();
        }

        return parent::runPaginationCountQuery($columns);
    }

View on GitHub (pinned to 0634653039)