$toDecimal is a MongoDB aggregation expression that converts a value to Decimal128—a precise decimal type. It is shorthand for { $convert: { input: <expr>, to: "decimal" } }.
Optional: multiply by quantity with $multiply for a line total.
If strings may be invalid, prefer $convert with onError.
Piece
Required?
Role
$toDecimal
Yes
Convert expression → Decimal128 (or null)
Expression
Yes
Number, numeric string, bool, Date, or decimal
$convert
No
Same conversion with error/null handling
Pseudocode
Pseudocode
for each document:
x = evaluate(expression)
if x is null or missing:
result = null
else if x is convertible (number, "4.99", bool, Date, …):
result = Decimal128(x)
else:
error // aggregation fails
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while converting to Decimal128.
Topic
Detail
Type
Aggregation expression (not a find filter)
Syntax
{ $toDecimal: <expression> }
Shorthand for
{ $convert: { input: <e>, to: "decimal" } }
String example
"4.99" → Decimal128("4.99")
Boolean
true → 1, false → 0
Date
Milliseconds since Unix epoch
vs $toDouble
Decimal128 is better for money precision
Try it
Live Preview
Pick an input and see the Decimal128-style result (browser demo of the same idea).
Simulates $toDecimal for numeric strings and booleans (same idea as the mongosh examples below).
Same conversion. Stage one builds convertedPrice like Example 2.
Multiply.$multiply does 2.50 × 5 = 12.50 and 4.99 × 2 = 9.98.
Project a slim result.$project keeps item and totalPrice.
Why Decimal128? Currency totals stay exact instead of drifting with binary floats.
Edge Cases & Pitfalls
Check these before using $toDecimal in production pipelines.
invalid
Non-numeric strings fail the pipeline
Values like "abc" throw a conversion error. Use $convert with onError for messy data.
null
Null and missing become null
$toDecimal returns null for null/missing inputs—it does not become zero.
base
Only base-10 strings
Hex-style strings such as "0x6400" are not accepted. Use $convert with a base option when needed.
vs double
Prefer decimal for money
$toDouble is fine for many metrics, but Decimal128 avoids classic float rounding issues in currency math.
Analysis
Performance Notes
Approach
Cost
Best for
$toDecimal per query
Per-document convert
Cleaning imported price strings
Store Decimal128
Cheapest long-term
Money fields you compute often
$convert + onError
Slightly more work
Dirty / nullable inputs
Prefer storing Decimal128 (or integers as cents) when you control writes. Converting on every read is fine for cleanup, but avoid repeated string→decimal work on hot paths.
Remember
Key Takeaways
Role: convert a value to Decimal128.
Money: prefer Decimal128 over double for currency.
Invalid: bad strings error—use $convert for soft fails.
Shorthand: same as $convert to "decimal".
One line:$toDecimal answers “turn this into a precise decimal so money math stays exact.”
Frequently Asked Questions
$toDecimal converts a value to Decimal128 inside an aggregation pipeline. Decimal128 is designed for precise decimal arithmetic—useful for money and accounting.
$toDouble uses binary floating point, which can round values like 0.1 + 0.2. $toDecimal uses Decimal128 for exact base-10 decimals, which is safer for currency.
$toDecimal is shorthand for { $convert: { input: <expr>, to: "decimal" } }. Use $convert with onError when invalid values should return a fallback instead of failing the pipeline.
$toDecimal returns null when the input is null or missing. Invalid non-numeric strings cause a conversion error.
Yes. false → Decimal128("0"), true → Decimal128("1"). A Date becomes the millisecond count since the Unix epoch as a decimal.
Base-10 numeric strings such as "4.99" or "-5.5". Non-decimal forms like "0x6400" are not accepted by $toDecimal.