<!-- llms-explorer concept facts · https://llms-explorer.com/tree/groupbydistinct-internal-stage/ · pack 2026-10-24 · ~1423 tokens -->

# $groupByDistinct internal stage

> Source-anchored research for $groupByDistinct internal stage. Run status: COMPLETED.

Parent: [MongoDB Advanced Explain: Aggregation, Sharded Plans, Loose Index Scans and the 8.3 Cost-Based Ranker](https://llms-explorer.com/tree/mongodb-advanced-explain-aggregation-sharded-plans-loose-index-scans-and-the-8-3-cost-based-ranker/) · 5 facets · 13 facts · page: https://llms-explorer.com/tree/groupbydistinct-internal-stage/

## Definitions

- A supported pattern is an index-compatible $sort followed by $group using $first/$last. The optimizer can replace grouping with a DISTINCT_SCAN cursor and a document transformation; the performance gain comes from skipping repeated group-key entries. (high confidence) — [source](https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/pipeline_d.cpp)

## How it works

- The inspected development source also attempts this rewrite for $top/$bottom groups when a suitable index matches their sortBy requirement. This source observation does not establish the first released version supporting those cases. (high confidence) (verified as of 2026-10-20) — [source](https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/pipeline_d.cpp)

## How-to and procedures

- Check explain('executionStats') for DISTINCT_SCAN, totalKeysExamined and totalDocsExamined. Index coverage is separate from duplicate skipping: a covered distinct plan can examine zero documents, while a first-document-per-group plan can include FETCH. (high confidence) — [source](https://www.mongodb.com/docs/manual/core/aggregation-pipeline-optimization/)

## Problems, failure modes and limitations

- The inspected executor requests strict distinct semantics because the transformation cannot remove duplicates itself. Its comments identify correctness hazards from traversing array-valued group keys and from sparse indexes omitting documents whose missing group key must count as null. (low confidence) (verified as of 2026-10-20) — [source](https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/pipeline_d.cpp)
- The inspected optimizer rejects the leading-sort rewrite when that sort already has an absorbed limit. This is a specific eligibility restriction; it does not say that a limit after the rewritten group is forbidden. (low confidence) (verified as of 2026-10-20) — [source](https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/pipeline_d.cpp)
- Rewrite eligibility does not guarantee a distinct plan: the executor-building path can return to ordinary planning when it cannot generate a viable distinct executor. (low confidence) (verified as of 2026-10-20) — [source](https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/pipeline_d.cpp)
- DevAdvisor's August 25, 2026 firsthand case reports a distinct-group benchmark returning 100 identifiers with 224 index entries examined and zero documents opened. Its roughly 22,000 entries at a 10,000-identifier production limit is explicitly an extrapolation, not a measured production result. (low confidence) (verified as of 2026-08-25) — [source](https://www.devadvisor.io/blog/08-2026_mongodb-distinct-scan-covered-index/)

## Facts and statements

- MongoDB's pipeline executor code describes a $groupByDistinct rewrite but constructs a stage named $groupByDistinctScan using DocumentSourceSingleDocumentTransformation. It replaces an eligible group with a transformation over DISTINCT_SCAN output. (high confidence) (verified as of 2026-10-20) — [source](https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/pipeline_d.cpp)
- In the inspected pipeline_d.cpp, $groupByDistinctScan is a DocumentSourceSingleDocumentTransformation that reshapes the representative document returned by DISTINCT_SCAN. The distinct executor must supply the deduplication; the replacement transformation does not deduplicate its input. (low confidence) (verified as of 2026-10-20) — [source](https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/pipeline_d.cpp)
- DISTINCT_SCAN does not imply a covered query: the published first/last example uses FETCH above DISTINCT_SCAN, while an independent reproduced example removes FETCH after adding the requested metadata field to the index. Check document reads separately from duplicate skipping. (high confidence) — [source](https://dev.to/franckpachot/firstlast-per-group-postgresql-distinct-on-and-mongodb-distinctscan-performance-1e9d)
- The min/max tickets do not establish released support. SERVER-94159 proposes extending the optimization; SERVER-108834 explains that naively taking the first sorted value for $min returns null for values [2,null,1], whereas $min should ignore null and return 1. (medium confidence) — [source](https://jira.mongodb.org/browse/SERVER-108834)
- A practical latest-document-per-group shape is $sort:{groupId:1,date:-1}, then $group:{_id:'$groupId',doc:{$first:'$$ROOT'}}, supported by {groupId:1,date:-1}. A MongoDB 7.0 reproduction reported DISTINCT_SCAN for this shape. (medium confidence) (verified as of 2023-10-03) — [source](https://stackoverflow.com/questions/77197237/mongodb-aggregation-group-stage-top-vs-first-efficiency-over-a-large-data-set)
- SERVER-98396 records that rewriting an aggregation to $groupByDistinct can be incorrect if a rooted $or uses a non-distinct index scan on one branch. The ticket was resolved January 28, 2025 with fix version 8.1.0-rc0; it is historical correctness evidence, not an assertion of a current unresolved bug. (low confidence) (verified as of 2025-01-28) — [source](https://jira.mongodb.org/browse/SERVER-98396)
