Pipeline stages and accumulators
For your first pipeline, read Aggregations. This reference lists accepted forms and limits so you can check a pipeline before moving it from MongoDB or Mingo.
The compiler currently implements 20 stage names and 18 group accumulator names, within the finite JSON data profile. This is an implemented subset, not full Mingo or MongoDB parity. The initial research examined MongoDB 8.3.8; executable differential checks in the captured validation run use MongoDB 8.0.29. No MongoDB 8.3 execution is claimed.
Implemented stages
These count aliases separately because they are distinct accepted Mongo stage names: $set/$addFields and $replaceRoot/$replaceWith.
Implemented group accumulators
Explicitly unimplemented
Stages include $setWindowFields, $graphLookup, $densify, $fill, $bucketAuto, $redact, $out, $merge, $geoNear, server/cluster metadata stages, Atlas search/vector/fusion stages, and other unlisted stages. No JS fallback exists.
Accumulators include $accumulator, $stdDevPop, $stdDevSamp, $median, $percentile, window-specific accumulators, and other unlisted accumulator names. Operator names shared with array expressions do not imply group-accumulator support; for example, an expression $concatArrays does not make the group accumulator $concatArrays available.
Also outside the current profile: BSON-only types, Decimal128, locale collation, timezone database semantics, MongoDB's full error codes/messages and resource limits, and exact query planner/index behavior. Optional native PCRE2 expressions are available when the extension is explicitly enabled. Primitive unsupported syntax is rejected before execution, including on an empty input. Some document-dependent semantic failures are deliberately raised inside SQLite and surface as its JSON validation error, rather than MongoDB's corresponding error code.
SQL strategy and performance
Every stage emits a SQL relation carrying JSON text doc and an ordering key ord. SQLite performs matching, joins, grouping, sorting, projection, and output assembly. JavaScript only compiles SQL and serializes/deserializes data. No JavaScript SQLite UDFs are registered.
Nested-array projection uses json_tree, recursive traversal, and iterative json_set reconstruction, not a fixed JS recursion limit on document array depth. Generated SQL size grows linearly with dotted path depth after factoring intermediate expressions; a 20-component $set path generates roughly 27 KB, rather than exponential text expansion. SQLite's own parser/expression/resource limits still apply.
For scalar sort keys, ordinary SQLite type rank plus scalar ORDER BY applies. If compound values occur, exact structural comparisons use an O(n²) SQL ranking fallback. This prioritizes correct JSON ordering over speed. It is expensive: in one local run, sorting 17 mixed scalar/object/array documents took roughly 250–315 ms; compound minN/maxN took about 1.5 seconds. Those are diagnostic observations, not performance guarantees or a benchmark claim. Compiled SQL for general semantic paths is considerably larger than hand-written scalar SQL. Optimizing typed scalar indexes, comparator normalization, and sort-key encoding is future work.
$lookup uses correlated SQL aggregation; no foreign collection is loaded into JS. Without an index-compatible foreign predicate it can still scan the foreign collection for each local document. Group arrays, facets, and lookup output arrays are constructed within SQLite, so persistent storage does not imply bounded size for one returned document. Streaming the final cursor avoids materializing the whole result set in JS; .toArray() intentionally collects results.
Validation evidence
- test/pipeline.test.js: 104 passing cases, including ordinary SQLite execution, Mingo differential examples, explicit Mongo expectations for known Mingo differences, join and failure regressions, and 23 captured real-Mongo expected results.
- test/mongo-pipeline.test.js: real MongoDB comparison for 23 edge cases (24 tests including the parent), including nested projection/set arrays, confirmed Mingo discrepancies, projection field order, lookup literal sources, and compound sort/min/max/top/bottom. Requires
MONGODB_URI; absent-server tests are marked skipped, not counted as passed conformance. - test/fixtures/mongo-pipeline-reference.json: the actual MongoDB 8.0.29 responses for those 23 cases, with version and capture time. The ordinary offline suite replays them against SQLite. To recapture with a real server, run
SILT_CAPTURE_MONGO_PIPELINE=1 node --test test/mongo-pipeline.test.jswithMONGODB_URIset. - The broader Mongo corpus and independent review tests are documented separately. These tests validate the listed examples; they do not establish exhaustive conformance for every operand combination.
Remaining known compatibility caveats
Projection retains source order for included fields, puts _id first, and appends computed fields in specification order. Dedicated tests compare serialized field order against MongoDB; ordinary JavaScript deep equality alone would not catch these differences. More combinations of nested mixed inclusion/computation remain useful conformance work.
Sorting on multiple array-valued paths is deliberately rejected, even where MongoDB can derive a correlated compound key. Scalar/object compound sorts and a single multikey path with other scalar keys are tested.
Very large/deep pipelines can hit SQLite parser, expression depth, compound SELECT, bind-variable, or JSON nesting limits before MongoDB's corresponding limits. Error translation and explicit configurable compiler budgets should be developed alongside performance work.