Skip to content

Build1 publisher2 min readPublished

DocumentDB 0.116 adds a $group distinct scan that reads one index entry per value

DocumentDB 0.116 lets a $group on PostgreSQL jump between distinct index values, so 100 groups over 50,000 entries need only 100 index reads. The saving scales with rows per value, and the published test had 500 per value with the feature switched on by flag.

The Engineer · Build desk

Illustration accompanying DocumentDB 0.116 adds a $group distinct scan that reads one index entry per value

What happened

  • DocumentDB 0.116, released on 20 August 2026, extends loose index scanning to $group queries that return one row per distinct grouping key.
  • DocumentDB implements the MongoDB API as a fully open-source extension to PostgreSQL.
  • A published test built 50,000 documents holding 100 distinct values of one field, with an ascending index on that field.
  • The test compared DocumentDB 0.114 with 0.116 and ran the newer version with the enableGroupByDistinctScan setting explicitly enabled.
  • On MongoDB 8.0.28, the reference engine, the plan was a covered DISTINCT_SCAN that examined 100 keys and no documents in 2 ms.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • capability On DocumentDB, a distinct-key $group over a field with many rows per value can finish after one index read per group, so its cost follows the group count.
  • constraint Pipelines whose $group has to see every row, such as one with an accumulator that adds values up, fall outside what the test exercised.
  • decision Validating 0.116 on a real collection also takes an explain without a hint, because the published run forced the a_1 index.

Every value of a appears 500 times in the a_1 index [12]. An ordinary index scan reads all 50,000 entries and leaves the aggregate to throw away the repeats [7]. A distinct scan reads the first entry for a value, then seeks to the next value and skips the other 499 [7][12].

MongoDB already had a DISTINCT_SCAN for first-and-last-per-group queries [14]. In the 8.0.28 reference run, that scan feeds an internal $groupByDistinctScan stage that builds each _id. A sort of the 100 results follows. It was estimated at 22,100 bytes and finished in memory with no spills [11].

DocumentDB 0.116 pairs the skip with its index-only access path [1]. The comparison was set up with care. The author ran VACUUM (ANALYZE) on both DocumentDB versions so their visibility state matched [9]. Without that step, a gap between 0.114 and 0.116 on an index-only path could come from table housekeeping instead of the planner [9].

According to the post, Microsoft is the main contributor and shapes the extension from enterprise customer feedback on Azure DocumentDB [3]. The author wrote, "In my opinion, DocumentDB is the only MongoDB emulation that translates MongoDB operators into native SQL access paths." [4] The $group distinct scan fits that description. A MongoDB pipeline stage gets compiled down to a PostgreSQL index access path [1][2].

The excerpt of the post stops before the DocumentDB plans for 0.114 and 0.116. That leaves MongoDB's plan as the only 100-key plan in the available text [10]. The 500-to-1 ratio also belongs to this dataset. A distinct scan reads one entry per distinct value [7]. Group on a field where all 50,000 values differ and it reads 50,000 entries, the same as the ordinary scan [13].

The 0.116 run had the feature switched on by hand [8]. After an upgrade I would check that setting first. Then I would confirm the plan with explain("executionStats"), the same call the test script used, before counting on the skip [15].

What to watch

  • The DocumentDB 0.114 and 0.116 execution plans from the same script, showing how many index keys PostgreSQL actually examined.
  • Whether a later DocumentDB release turns enableGroupByDistinctScan on by default.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories