Skip to content
Monghoul

What each MongoDB release added to the aggregation language, from 5.0 on

The answer to "why does $percentile not work" is almost always the server version. Here is what arrived in each release from 5.0 to 8.3.

· ·updated 13 September 2026 ·checked against MongoDB 3.2 through 8.3
A row of black blocks of very unequal width, some solid and some outlined, running across the upper left of the frame. One narrow blue block sits below a gap in the row, alone in open space.
Each block is one release, and the releases are not the same size. The blue one has dropped out of the row: that is a version your cluster does not have, and everything it added is out of reach.

A pipeline that works on your laptop and fails on staging is usually not a pipeline problem. It is a version problem, and MongoDB reports it in a way that sends people looking in the wrong place: Unrecognized expression '$percentile' reads like a typo, not like “your server is two major versions behind the documentation you were reading”.

The documentation does say which version each operator needs. It says it on the operator’s own page, one page at a time, which is the wrong shape for the question you actually have. The question is almost always “we are pinned to 6.0, what can I use”.

So here is the list the other way round.

5.0

The biggest single release for the aggregation language in years. Window functions arrived, and so did date arithmetic that does not involve doing sums on milliseconds.

Window operators, all of which need $setWindowFields: $expMovingAvg, $rank, $denseRank, $documentNumber, $shift, $derivative, $integral, $covarianceSamp, $covariancePop.

Date arithmetic: $dateAdd, $dateSubtract, $dateDiff, $dateTrunc. Before these, “group by week” meant $subtract against epoch milliseconds and hoping about time zones.

Field access by name: $getField, $setField, $unsetField. These are the answer to a field whose name contains a dot or starts with a dollar, which was awkward to reach before.

Also the $count accumulator, for use inside $group. The $count stage is much older and is a different thing, which the cheat sheet is careful to separate and which is easy to conflate. And let as an option on the aggregate command itself, which keeps a parameter out of the pipeline body so the shape stays cacheable. That is not $lookup’s let, which arrived in 3.6.

5.1, 5.2 and 5.3

Rapid releases, and this is where the version question gets sharp: these are Atlas-only in practice for most people, so a self-hosted cluster on 5.0 does not have them.

  • 5.1: $densify, $tsSecond, $tsIncrement
  • 5.2: $top, $topN, $bottom, $bottomN, $firstN, $lastN, $minN, $maxN, $sortArray
  • 5.3: $fill, $linearFill

The 5.2 accumulators are worth knowing about, because “the three highest scoring documents per group” was genuinely awkward before $topN and is one line after it.

6.0

Quieter than its number suggests. $documents is the addition people actually use, and it is mostly a testing convenience: a pipeline that starts from literal documents rather than a collection.

$shardedDataDistribution arrived in 6.0.3, which is a patch release, so “we are on 6.0” is not enough to answer whether you have it.

6.3

Bitwise operators: $bitAnd, $bitOr, $bitXor, $bitNot. Late, and useful precisely once, when somebody stored flags in an integer.

7.0

$median and $percentile, which is the pair most often reached for and most often missing. If you are on 6.0 and want a percentile, you are computing it in application code or with $sortArray and arithmetic.

Also $listSampledQueries and the $$USER_ROLES system variable.

8.0 and later

  • 8.0: $querySettings, $toUUID, $toHashedIndexKey
  • 8.2: $score, $minMaxScaler, $sigmoid, and the encrypted string predicates $encStrStartsWith, $encStrEndsWith, $encStrContains, $encStrNormalizedEq
  • 8.3: $scoreFusion, $toArray, $toObject, $createObjectId, $hash, $hexHash, $similarityCosine, $similarityDotProduct, $similarityEuclidean

The 8.2 and 8.3 additions are mostly about search scoring and vector similarity, which is where the server has been putting its effort.

What this list does not cover

It starts at 5.0 and it lists the releases the reference carries entries for, so the rapid releases in between with nothing new in the aggregation language do not get a heading. If an operator you are looking for is not here, that is not the same as it not existing: check the cheat sheet, which carries a since marker on every entry from 3.2 onward and is where the versions in this piece come from.

The ones that are not a version at all

Four things in the reference are gated on the deployment rather than the release, and this catches people out because the error looks identical:

  • $search and $searchMeta need Atlas. They do not exist on a self-hosted server at any version.
  • $vectorSearch needs Atlas 6.0.11 or 7.0.2 and later.
  • $queryStats needs Atlas M10 or larger.
  • $listSearchIndexes is 7.0, backported to 6.0.7.

That last pattern, a feature backported into a patch release of the previous major, appears more than once: $changeStreamSplitLargeEvent is 7.0 and 6.0.9, $listClusterCatalog is 8.0.10. So the honest answer to “do we have it” is db.version(), not the major number somebody remembers.

Checking without guessing

db.version();

Then read the list above. If you want the other direction, an operator and what it needs, the aggregation cheat sheet carries a since marker on every entry from 3.2 through 8.3, which is where the version data in this piece comes from.

One habit worth having on a team that runs more than one cluster: pin the version you develop against to the oldest version you deploy to. The alternative is finding out at the point where it is most expensive to find out.