MongoDB $toDecimal Operator

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $toDecimal?

$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" } }.

Remember
$toDecimal = convert value → Decimal128

{ $toDecimal: <expression> }

numbers / numeric strings → decimal
true → 1, false → 0
Date → millis since epoch
null / missing → null
invalid string → pipeline error

Prefer for money (vs $toDouble)
UsePrefer
Precise decimal / money math$toDecimal
Binary floating point$toDouble
Convert with onError / onNull$convert

How to Use $toDecimal in MongoDB

Convert prices (or other decimals), then multiply, add, or compare.

  1. Choose an expression stage ($addFields or $project).
  2. Pass the number or numeric string to $toDecimal.
  3. Optional: multiply by quantity with $multiply for a line total.
  4. If strings may be invalid, prefer $convert with onError.
PieceRequired?Role
$toDecimalYesConvert expression → Decimal128 (or null)
ExpressionYesNumber, numeric string, bool, Date, or decimal
$convertNoSame 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 }

Cheat Sheet

Keep these facts handy while converting to Decimal128.

TopicDetail
TypeAggregation expression (not a find filter)
Syntax{ $toDecimal: <expression> }
Shorthand for{ $convert: { input: <e>, to: "decimal" } }
String example"4.99" → Decimal128("4.99")
Booleantrue → 1, false → 0
DateMilliseconds since Unix epoch
vs $toDoubleDecimal128 is better for money precision

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).

Result
input = "4.99"
$toDecimal → Decimal128("4.99")

{ asDecimal: Decimal128("4.99") }

Worked Walkthrough — Line Total

Price is stored as the string "2.50" with quantity 5. Convert, then multiply for the line total.

Calculation
Document:
  { item: "apple", qty: 5, price: "2.50" }

$toDecimal("2.50") → Decimal128("2.50")

total = price × qty
      = 2.50 × 5
      = Decimal128("12.50")

Check: 5 apples at $2.50 each = $12.50 ✓

MongoDB Examples

Insert sample orders with string prices, convert with $toDecimal, then compute line totals. Run these in mongosh in order.

Example 1 — Sample Data

Two orders store price as a numeric string (common with imported CSV/JSON).

mongosh
db.orders.insertMany([
  { _id: 1, item: "apple", qty: 5, price: "2.50" },
  { _id: 2, item: "pie", qty: 2, price: "4.99" }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps two documents in orders. Run find() to see them:

mongosh
db.orders.find()

Read the rows like this:

FieldExamplesPlain English
_id1, 2Document id
item"apple", "pie"Product name
qty5, 2Quantity (number)
price"2.50", "4.99"Unit price stored as a string

How It Works

  1. Insert two orders. insertMany stores simple documents for the lesson.
  2. Prices are strings. MongoDB does not auto-convert "2.50" to Decimal128 on insert.
  3. Ready to convert. The next example turns those strings into decimals.

Example 2 — Convert with $toDecimal

Goal: add a convertedPrice field as Decimal128 for every order.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      convertedPrice: { $toDecimal: "$price" }
    }
  }
]);

How It Works

  1. Read each price string. Values come from Example 1.
  2. Convert to Decimal128. $toDecimal parses base-10 numeric strings.
  3. Precision stays decimal. "4.99" becomes Decimal128("4.99"), not a binary float surprise.
  4. Keep originals. $addFields adds convertedPrice without removing price.

Example 3 — Line Total

Convert the price, then multiply by quantity for each line total.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      convertedPrice: { $toDecimal: "$price" }
    }
  },
  {
    $project: {
      item: 1,
      totalPrice: {
        $multiply: ["$convertedPrice", "$qty"]
      }
    }
  }
]);

How It Works

  1. Same conversion. Stage one builds convertedPrice like Example 2.
  2. Multiply. $multiply does 2.50 × 5 = 12.50 and 4.99 × 2 = 9.98.
  3. Project a slim result. $project keeps item and totalPrice.
  4. 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.

Performance Notes

ApproachCostBest for
$toDecimal per queryPer-document convertCleaning imported price strings
Store Decimal128Cheapest long-termMoney fields you compute often
$convert + onErrorSlightly more workDirty / 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.

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.

Next: $toDouble

Convert values to double in an aggregation pipeline.

$toDouble tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful