Skip to main content

Module mongodb

Module mongodb 

Source
Expand description

MongoDB backend: compiles the supported subset of a QueryPlan / WritePlan to filters, update documents and aggregation pipelines.

  • compile is a pure compiler (no server needed, unit-tested).
  • MongoBackend executes compiled plans (MongoDB 5.0+; transactions need a replica set) and implements the same Backend / Executor traits as the SQL adapters, so it plugs into Db.
  • value maps Value to and from BSON.

Anything the backend cannot express fails before any I/O, with a capability error (BackendCapabilities::mongodb, checked through QueryPlan::check / WritePlan::check) or QueryError::InvalidPlan.

§Collections and keys

A table is a collection of the same name. Plans carry no model metadata, so the adapter needs to know which column is the primary key: it is the column named id unless Keys says otherwise (MongoBackend::with_keys(Keys::default().with("tags", "slug"))). That column is stored as _id and nowhere else; filters, projections, sort keys and update targets are translated, and _id is renamed back on read. A key the plan does not supply (an insert that omits it) is generated as an i64 from a counter document in siderite_counters ($inc by the batch size, so a bulk insert gets consecutive keys in input order; the counter lives outside the transaction like a sequence, so a rollback leaves a gap). Explicitly supplied keys do not advance the counter. A collection whose key column is not registered still works, but its key column is then an ordinary field next to a generated _id, and duplicates of it are not rejected.

§Mapping table

§QueryPlan fields

FieldMongoDB
source (table)collection
source (derived table, from_subquery)inner pipeline followed by the outer stages (used by count, exists, aggregate on limited / distinct / grouped querysets)
projectionfinal $project (_id: 0, one computed field per output name); empty = whole documents with _id renamed to the key column
joinscapability error Feature::Joins (also select_related / Related columns)
filterleading $match: query operators where a predicate has a query form, otherwise {$expr: ..}
grouping$group with _id: {k0: .., k1: ..} (_id: null when only aggregates are projected)
having$match with $expr after $group
ordering$sort (plain columns sort directly, other expressions through a temporary $addFields; NULLs sort first ascending, as on SQLite)
limit / offset$limit / $skip
distinct: All$group on the projected fields, then $replaceRoot; ordering must then use projected expressions
distinct: Oncapability error Feature::DistinctOn
lockcapability error Feature::RowLocking / LockModifiers
compound (set operations)capability error Feature::SetOperations

A grouped plan needs an explicit projection, and every non-aggregate expression in it, in having and in ordering must be a grouping key or a projected alias (anything else is InvalidPlan). A single ungrouped COUNT(*) compiles to $count. An ungrouped aggregate over no documents still yields one row (COUNT is 0, the rest NULL), as in SQL.

§WritePlan

PlanMongoDB
Insertinsert_many (ordered); the key column becomes _id; keys are generated when absent (see above); returning echoes the stored documents in input order
Updateupdate_many; literal assignments use {$set: {..}}, F-expression assignments use an update pipeline ([{$set: {..}}], every expression sees the original document); rows_affected is the matched count; returning first pins the matching _ids, updates them, then reads them back by _id; the key column cannot be assigned
Deletedelete_many; returning reads the documents first

§Expr nodes

Predicates follow SQL three-valued logic: a row passes only when the predicate is true. MongoDB’s $ne, $nin, $not and $nor match NULL and missing fields and $expr comparisons use BSON type order, so negation is pushed down (De Morgan) with explicit non-NULL guards, and $expr comparisons, NOT, AND and OR are compiled with a NULL branch.

NodeFilter (query form)Aggregation expression ($expr, projections, sorts, updates)
Columnfield (_id for the key)"$field"; boolean column as predicate: {f: true}
Valueoperand{$literal: bson}; NULL is null
Binary comparison{f: {$eq/$lt/$lte/$gt/$gte: v}}; <> is {$nin: [v, null]}; = NULL is {f: null}$eq/$ne/$lt/$lte/$gt/$gte guarded by $cond so a NULL operand gives NULL
Binary arithmeticnot a predicate$add, $subtract, $multiply, $divide, $mod ($divide is always floating point, unlike SQL integer division)
UnaryNot pushes negation down; Neg n/aNot: NULL-preserving $not; Neg: $multiply: [x, -1]
And / Or$and / $or; empty And is {}, empty Or is {$expr: false}Kleene logic with $in: [false/true/null, [..]]
Lookup::IExact{f: {$regex: "^escaped\\z", $options: "i"}}$regexMatch (text only, else NULL)
Lookup::Contains / StartsWith / EndsWith$regex on the escaped needle, $options: "i" when case-insensitive, anchored with ^ / \z$regexMatch
Lookup::Regex{f: {$regex: p}}$regexMatch
Lookup::In$in ($nin with null when negated)$in with a literal array
Lookup::Range{$gte, $lte} ($or of $lt / $gt when negated)$and of $gte / $lte
Lookup::IsNull{f: null} / {f: {$ne: null}}$eq: [{$ifNull: [x, null]}, null]
Lookup::InSubquery, Exists, Subquerycapability error Feature::Subqueriessame
OuterRefInvalidPlan (only valid inside a subquery)same
Relatedcapability error Feature::Joinssame
Func::Lower / Upper / Length / Trimvia $expr$toLower, $toUpper, $strLenCP, $trim (NULL in, NULL out)
Func::Coalescevia $expr$ifNull
Func::Concatvia $expr$concat with each argument wrapped in $ifNull: [x, ""]
Func::Substrvia $expr$substrCP with start - 1 (1-based), length defaults to the rest
Func::Replacevia $expr$replaceAll
Castvia $expr$convert to long / double / decimal / bool / string / date (SmallInt, Integer, BigInt, Real, Double, Decimal, Bool, Text, Timestamp); other targets are InvalidPlan
Casevia $expr$switch (default NULL)
DatePartvia $expr$year, $month, $dayOfMonth, $isoWeek, quarter from $month, $hour, $minute, $second, $dateToString (%Y-%m-%d) for Date. Dates and times are stored as text, so a string operand is parsed with $dateFromString (dates) or sliced (times)
Aggregate::Count(*){$sum: 1} ($count alone)
Aggregate::Count(x)$sum of 1 per non-NULL value; DISTINCT via $addToSet and $size
Aggregate::Sum$sum plus a count of numeric values so an all-NULL group is NULL, not 0
Aggregate::Avg / Min / Max$avg / $min / $max
Aggregate::StdDev / Variance$stdDevSamp / $stdDevPop; variance is $pow of the deviation by 2 (statistical aggregates are supported)
Aggregate::StringAgg$push (or $addToSet) then $reduce with $concat (element order is unspecified)
Aggregate::ArrayAggcapability error Feature::Arrays
Aggregate filterthe argument becomes {$cond: [filter, x, null]}, which every accumulator ignores
Windowcapability error Feature::WindowFunctionssame

§Values

ValueBSON
Nullnull
Boolboolean
Intint64 (int32 and int64 both decode)
Floatdouble
DecimalDecimal128 (exact, sums and averages stay decimal)
Textstring
Bytesbinary, generic subtype
Uuidbinary subtype 4 (16 bytes)
TimestampBSON datetime, millisecond precision: microseconds are truncated on write, so a value read back can differ from the one written; insert/update returning rows reflect what was stored
Date, Timecanonical text as on SQLite (%Y-%m-%d, %H:%M:%S%.6f), which sorts and compares correctly
Jsonobjects and arrays are embedded documents / arrays (numbers become int64 or double; integers above i64::MAX are rejected); JSON scalars are stored as their JSON text (5, "x") so they decode back unchanged

Decoding is by BSON type: documents and arrays become Value::Json, ObjectIds become hex text, other unsupported types are decode errors.

§Transactions

begin starts a session and a transaction (TransactionSupport::Flat). There are no savepoints, so a nested Db::transaction (and therefore bulk_create on a transactional handle) is a capability error, and no isolation level can be requested. Dropping a transaction aborts it. MongoDB has no foreign keys: ON DELETE actions do nothing, and unique constraints exist only where MongoBackend::create_unique_index made one (plus _id). Duplicate-key and document-validation failures map to BackendError::Constraint.

§Raw access

raw_sql, raw_execute and execute_script are capability errors (Feature::RawSql); MongoBackend::raw_command runs a database command instead.

Re-exports§

pub use compile::Keys;

Modules§

compile
Pure compiler: plans to MongoDB filters, update documents and pipelines.
value
Canonical mapping between Value and BSON.

Structs§

MongoBackend
MongoDB adapter: compiles plans to filters and pipelines and runs them.