mongodb/mongo
Query engine
The query engine plans, optimizes, and executes find/update/delete operations and the early stages of aggregation pipelines. Two engines coexist in the tree: the classic engine (src/mongo/db/exec/classic/) and the slot-based engine (SBE) (src/mongo/db/exec/sbe/). Planning, parsing, and shared infrastructure live under src/mongo/db/query/ (25+ subdirectories).
Purpose
Given a find (or one of its relatives) the engine must:
- Parse the query into a MatchExpression AST.
- Resolve indexes and collation.
- Produce candidate query plans.
- Pick the best plan (multi-planning) or read it from the plan cache.
- Execute the plan through a tree of
PlanStage(classic) orPlanStageslot graph (SBE). - Stream documents back to the client through a
ClientCursor.
Pipeline of a find
graph TD
Parse[Parse: find_command_request_test] --> CQ[CanonicalQuery]
CQ --> Planner[QueryPlanner]
Planner -->|candidate plans| MultiPlanner[MultiPlanner / cached plan]
MultiPlanner -->|chosen plan| Builder[StageBuilder]
Builder -->|classic| ClassicTree[Classic PlanStage tree]
Builder -->|sbe| SbeTree[SBE PlanStage tree]
ClassicTree --> Cursor[ClientCursor]
SbeTree --> Cursor
Cursor -->|getMore| ClientThe split between classic and SBE happens at the stage builder step. SBE was introduced in 5.0 (Jul 2021) as an opt-in fast path; subsequent releases have progressively expanded the set of plans handed to SBE. The decision is made by query_planner_common.cpp and the SBE feature compatibility checks.
Major directories
src/mongo/db/query/
├── canonical_query.cpp # The validated, optimized query.
├── query_planner.cpp # Generates candidate plans.
├── plan_cache/ # Cache from query shape -> winning plan.
├── plan_enumerator/ # Enumerates plan alternatives.
├── plan_ranking/ # Multi-planning to pick the best alternative.
├── stage_builder/ # Translates QuerySolution -> PlanStage tree.
├── compiler/ # AST -> intermediate representation.
├── algebra/ # Algebra over query operations.
├── client_cursor/ # ClientCursor and cursor manager.
├── collation/ # Collation rules.
├── plan_cache.h # Cache entry point.
├── query_settings/ # Per-query overrides (cluster-wide).
├── query_shape/ # Stable hash of a query's shape.
├── query_stats/ # Aggregated stats by query shape.
├── fle/ # Queryable Encryption query rewrites.
├── search/ # $search / Atlas Search integration.
├── timeseries/ # Time-series query rewrites.
└── write_ops/ # Update/delete planning.
src/mongo/db/exec/
├── classic/ # Classic execution engine.
├── sbe/ # Slot-based execution engine.
├── agg/ # Aggregation execution.
├── express/ # Fast-path execution for simple plans.
├── document_value/ # Document/Value model used by aggregation/SBE.
├── expression/ # Expression evaluation.
├── matcher/ # MatchExpression evaluation.
├── runtime_planners/ # Plan switching at runtime (SBE).
└── timeseries/ # Bucket-aware execution.Classic engine
The classic engine is a tree of PlanStage objects, each pulling documents from its child via work(). The shape is similar to a Volcano-style iterator pipeline:
LIMIT
└── SORT
└── SKIP
└── FETCH
└── IXSCAN(index: {a:1})Stages are in src/mongo/db/exec/classic/. The work() interface yields control on every iteration so the storage engine can cooperate with locking and read concern.
Slot-based engine (SBE)
SBE represents plans as a graph of PlanStages that exchange data via slots — typed registers carrying values across stages. SBE plans:
- Avoid the per-document overhead of the classic engine for common shapes.
- Use a vectorized expression compiler to evaluate predicates and projections.
- Have a different runtime planner that can switch between trial plans dynamically.
SBE is in src/mongo/db/exec/sbe/. The expression compiler lives at src/mongo/db/exec/expression/.
Plan cache
Repeated queries with the same shape (same predicates, same projections, same sort) reuse the same plan from the plan cache (src/mongo/db/query/plan_cache/). Cache keys are computed by the query shape module (src/mongo/db/query/query_shape/), which hashes the structural form of a query while ignoring concrete values.
The cache stores:
- The winning plan's
QuerySolution. - Multi-planning statistics so it can be invalidated when its assumptions stop holding (e.g. data changes, indexes are dropped).
- Per-shape
PlanCacheEntrys keyed by collection and query shape.
db.collection.aggregate([{$planCacheStats: {}}]) is the operator-facing view.
Query stats and query settings
- Query stats (
src/mongo/db/query/query_stats/) aggregates per-shape statistics (latency, doc count, plan summary) across the cluster. Useful for "which queries are running on my cluster?". - Query settings (
src/mongo/db/query/query_settings/) is a cluster-wide knob set per query shape — for example, force a particular index hint for all queries that match a given shape.
ClientCursor
A ClientCursor is the server-side state of an open cursor (a find or aggregation that hasn't been fully drained). The CursorManager (src/mongo/db/cursor_manager.h) tracks open cursors, enforces idle timeouts, and reaps abandoned cursors. The mongos has its own ClusterCursorManager (src/mongo/s/query/cluster_cursor_manager.h) for cursors that fan out across shards.
Key source files
| File | Purpose |
|---|---|
src/mongo/db/query/canonical_query.cpp |
The validated query object. |
src/mongo/db/query/query_planner.cpp |
Plan enumeration. |
src/mongo/db/query/plan_cache/ |
Plan cache. |
src/mongo/db/query/stage_builder/ |
QuerySolution → PlanStage tree. |
src/mongo/db/exec/classic/ |
Classic execution stages. |
src/mongo/db/exec/sbe/ |
Slot-based execution. |
src/mongo/db/exec/agg/ |
Aggregation pipeline execution. |
src/mongo/db/exec/express/ |
Fast-path execution for simple plans. |
src/mongo/db/cursor_manager.h |
Server-side cursor lifecycle. |
Integration points
- The storage engine provides the
RecordStoreandSortedDataInterfacethe classic and SBE scans walk. - The aggregation pipeline uses the same
Pipeline/DocumentSourceframework but runs through the agg execution engine; some stages "lower" into SBE. - The shard role owns the
acquireCollectionAPI the planner uses to consult collection metadata. - The query stats and query settings systems span
mongodandmongos.
Entry points for modification
Adding a new query language operator usually means a new MatchExpression subclass under src/mongo/db/matcher/, a parser entry, and a pair of executor implementations (classic + SBE). Plan-cache changes are concentrated in src/mongo/db/query/plan_cache/. New index types add a IndexAccessMethod and integrate via src/mongo/db/index/. The query_golden test suites pin plan output and require explicit acknowledgment when output changes.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.