Implements the mongodb-superpowers-package design: Stable Tasks 1-50 and Advanced Tasks 1-15. The design assumes 19 Stable + 12 Advanced Gradle projects under modules/mongodb*. This repository's fail-closed registry declares exactly 19 leaf identities, so those modules become package boundaries inside the registered leaf :adapter:outbound:persistence-mongo, with the design's module dependency table enforced by ten ArchUnit rules. The mapping and every deviation are recorded in docs/mongodb/repository-adaptation.md. Contract highlights, all enforced by tests rather than convention: - Transaction body retry and commit retry are separate loops. A new session per body attempt; commit-only retry on an unknown commit. The body is never replayed after a commit ambiguity, so a failover cannot become a duplicate. - MongoExecutionOutcome keeps both ambiguous outcomes distinct from success and failure, and MongoFailureContext records only the design-permitted fields. - Failure classification reads server error labels before numeric codes. - BSON representations come from a pinned manifest, never a library default, and a golden type-signature gate fails on any drift. - Index and validator changes go through the manifest and the admin plane; metadata ownership gates every drop. - Every Advanced capability refuses construction unless its flag is enabled. Verified against real servers, not only unit tests. Running the lanes for the first time exposed four defects that a green `check` had hidden: - Four release lanes passed while executing zero tests; the gate now counts executed tests per lane and fails on zero. - The "single replica set" fixture was a standalone, because Testcontainers 2.x needs withReplicaSet(); its test only asserted a connection string. - The three-node fixture was three independent clusters, so no election could occur, and awaitNewPrimary() compared against the post-stop primary. - The migration lease checked modifiedCount, so a same-millisecond refresh read as a lost lease. scripts/verify-mongodb-platform.sh now reports: 9 lanes, 0 skipped, 0 failed, every evidence category produced. scripts/verify-mongodb-advanced.sh reports NOT PROMOTABLE: actual-topology evidence (real sharded cluster, real KMS, real target deployment) is unobtainable here, so it is named rather than assumed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6.2 KiB
Query and Aggregation Guide
Design §17–§19, decision D-11. Every query and every pipeline is a registered, bounded thing. Free-form JSON queries and unbounded pipelines are explicitly unsupported (§3.4).
1. Registered operations
Every execution carries a MongoOperationContext: a MongoOperationName, a DatabaseProfileName, a
CollectionProfileName, a MongoOperationType and a MongoOperationScope.
MongoOperationName matches [a-z][a-z0-9.-]{2,95}. It is the join key for the budget registry, the
consistency registry, the metric tag and the log line — a free-form or interpolated name breaks all
four at once, which is why the pattern is enforced at construction.
MongoOperationScope uses an UNSPECIFIED sentinel rather than null, so "the caller did not say"
is a value the policy layer can reject rather than an NPE further down.
2. Query guardrails
PolicyAwareMongoQueryBuilder builds a query from MongoFieldDescriptor + MongoOperator pairs
against a MongoQueryPolicy. The policy refuses:
- a field not in the collection's allowlist
- an operator not allowed for that field
- a sort on an unindexed field
$where,$exprwith arbitrary JavaScript, and server-side evaluation generally- an unbounded
$regex
MongoRegexPolicy requires an anchored prefix pattern and bounds the pattern length. An unanchored
regex is a collection scan wearing an index's clothes, and a user-supplied one is a denial-of-service
primitive.
MongoSortDescriptor pairs a field with a direction and is validated against the index manifest, so
a sort that would spill to disk fails review rather than production.
3. Operation budgets
MongoOperationBudget bounds four things at once:
| Bound | Why |
|---|---|
maxTimeMS |
The server stops working on a query nobody is waiting for. |
| result limit | An unbounded result set is an OOM with extra steps. |
| batch size | Bounds the per-round-trip memory. |
| examined-document ceiling | Catches an index regression that a time limit alone would hide on a fast day. |
MongoBudgetPolicyRegistry binds a budget to an operation name; MongoBudgetEnforcer applies it and
raises MongoOperationRejectedException before execution when a request exceeds it, and
MongoTimeoutException when the server enforces it.
4. Keyset pagination
Unbounded skip is unsupported: skip(1_000_000) makes the server walk a million documents to throw
them away, so page 1000 costs a thousand times page 1.
MongoKeysetQueryBuilder builds the resume predicate lexicographically. For a sort on (a DESC, _id DESC) resuming after (A, I):
(a < A) OR (a = A AND _id < I)
validate() rejects a MongoKeysetSort without a unique tie-breaker. Without one, two documents with
the same sort value straddle the page boundary and one of them is skipped or repeated — invisibly,
and only under concurrency.
MongoNullSortOrdering makes null placement explicit, because MongoDB's own ordering of missing
versus null versus present is not what most people assume.
Cursors are authenticated
MongoKeysetCursorCodec signs the cursor with HMAC-SHA256 and compares with
MessageDigest.isEqual (constant time). An unsigned cursor is a client-controlled query predicate: a
caller can edit it to read a range they were never offered. A tampered or truncated cursor yields
MongoCursorException, never a partially-decoded resume position.
5. Aggregation guardrails
MongoAggregationPlan is a registered pipeline: an ordered list of MongoAggregationStageDescriptor
validated against a MongoAggregationProfile. PolicyAwareMongoAggregationExecutor runs only a
registered plan.
MongoAggregationRisk grades each stage, and the profile sets the ceiling:
| Risk | Stages | Policy |
|---|---|---|
| low | $match on an indexed prefix, $limit, $project |
Always allowed. |
| moderate | $group, $sort with an index, $unwind with a bound |
Allowed within budget. |
| high | $lookup, $graphLookup, $facet, unindexed $sort |
Requires explicit approval in the profile. |
| forbidden | $out, $merge outside the admin plane, $function, $accumulator |
Refused. |
allowDiskUse is a declared property of the plan, not a runtime flag. A pipeline that needs disk is a
pipeline whose shape should be reviewed.
6. Reactive execution and cursors
ReactiveMongoExecutor / DefaultReactiveMongoExecutor carry the operation context in the Reactor
context. MongoCursorGuard and MongoCursorLease bound cursor lifetime:
- a cursor has a lease with a deadline
- cancellation closes the server-side cursor (
MongoCursorTermination) - an abandoned cursor is a server-side resource, so the lease is released on cancel, error and
completion —
MongoReactiveCursorPublisherusesFlux.usingso all three paths run the same release
A leaked cursor does not fail anything locally; it consumes a connection and a snapshot on the server until the server's own timeout, which is why the guard is not optional.
7. Geospatial
MongoGeoQuery + MongoGeoPoint + MongoGeoDistance over a 2dsphere index. Distances are metres
on a sphere (nearSphere with maxDistance), never degrees — a degree of longitude is a different
distance in Oslo than in Nairobi, and a radius expressed in degrees is a bug that only shows up away
from the equator. SpringMongoGeospatialOperations is the Spring Data binding;
MongoGeospatialOperations is the port.
8. Native capability gateway
When a registered operation genuinely needs something outside the Stable API, it goes through
MongoNativeCapabilityGateway (PolicyAwareMongoNativeGateway), never through the driver directly.
The admission order is fixed:
capability registered
→ database profile
→ collection allowlist
→ operation name present
→ timeout / maxTimeMS
→ consistency profile
→ result / batch limit
→ trace
→ log redaction
→ command category (MongoNativeCommandCategory)
→ D4 admin command refused
→ execute
ApprovedMongoNativeOperation is the registration record; MongoNativeOperationPolicy is the policy.
An admin-plane command reaching this gateway is refused regardless of capability — the admin plane has
its own credential and its own client (see security-observability.md).