MongoDB $toDecimal Operator

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 5 Examples
Type Conversion

What You’ll Learn

The $toDecimal operator converts values to Decimal128 in MongoDB aggregation pipelines. Use it for financial data, currency calculations, and any scenario where floating-point rounding errors are unacceptable.

01

Decimal128

High-precision type.

02

Syntax

One expression.

03

Precision

No float rounding.

04

$project Stage

Parse price fields.

05

Use Cases

Finance, e-commerce.

06

vs $toDouble

Exact vs floating.

Definition and Usage

In MongoDB’s aggregation framework, the $toDecimal operator converts an expression to a BSON Decimal128 value. Standard doubles use binary floating point, which can produce surprising results — for example, 0.1 + 0.2 may not equal exactly 0.3. Decimal128 stores numbers as exact decimal values, making it the right choice for money, tax calculations, and accounting reports.

$toDecimal is shorthand for { $convert: { input: <expression>, to: "decimal" } }. It is part of the type-conversion family alongside $toInt, $toDouble, and $toString.

💡
Beginner Tip

Use $toDecimal when working with currency. For general scientific or statistical math where tiny rounding differences are acceptable, $toDouble is often sufficient and slightly faster.

📝 Syntax

The $toDecimal operator takes one expression:

mongosh
{ $toDecimal: <expression> }

Literal Examples

mongosh
{ $toDecimal: "29.99" }
// Result: Decimal128("29.99")

{ $toDecimal: 100 }
// Result: Decimal128("100")

{ $toDecimal: "$price" }
// Convert the price field

{ $toDecimal: { $multiply: [ "$qty", "$unitPrice" ] } }
// Convert a computed expression

Conversion Rules

  • null — returns null.
  • Decimal128 — returns the same decimal value.
  • String — parses numeric strings (invalid strings cause an error).
  • Number — converts int, long, double, and decimal to Decimal128.
  • Booleantrue becomes 1, false becomes 0.
  • Use inside $project, $addFields, $set, or $group.

💡 $toDecimal vs $toDouble

$toDecimal — Decimal128; exact decimal representation; best for currency
$toDouble — binary floating point; faster; may have rounding errors
Example: 0.1 + 0.2 with doubles may not equal 0.3 exactly; decimals preserve precision
Use $toDecimal for money; use $toDouble for general numeric work

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (type conversion)
Syntax{ $toDecimal: <expression> }
Output typeDecimal128
Equivalent{ $convert: { input: <expr>, to: "decimal" } }
Best forCurrency, tax, accounting precision
Common stages$project, $addFields, $group
String
{
  $toDecimal: "$price"
}

Parse price text

Literal
{
  $toDecimal: "19.99"
}

Fixed decimal

Sum
{
  $sum: {
    $toDecimal: "$amount"
  }
}

Precise totals

Multiply
{
  $multiply: [
    { $toDecimal: "$qty" },
    { $toDecimal: "$rate" }
  ]
}

Exact math

Examples Gallery

Convert string prices to Decimal128, compute line totals with precision, and sum order amounts without floating-point rounding errors.

📚 Product Prices

Start with an orders collection where prices are stored as strings and convert them with $toDecimal.

Sample Input Documents

Suppose you have an orders collection with string prices from a CSV import:

mongosh
[
  {
    "_id": 1,
    "product": "Widget A",
    "price": "29.99",
    "quantity": 2
  },
  {
    "_id": 2,
    "product": "Widget B",
    "price": "15.50",
    "quantity": 3
  },
  {
    "_id": 3,
    "product": "Widget C",
    "price": "0.10",
    "quantity": 10
  }
]

Example 1 — Convert String Price to Decimal128

Parse the price string into a precise decimal value:

mongosh
db.orders.aggregate([
  {
    $project: {
      product: 1,
      price: 1,
      unitPrice: { $toDecimal: "$price" }
    }
  }
])

How It Works

$toDecimal parses numeric strings into Decimal128. The value is stored as an exact decimal, not a binary approximation.

📈 Financial Calculations

Compute line totals and order sums with precise decimal arithmetic.

Example 2 — Calculate Line Total with Precision

Multiply quantity by unit price using decimal values:

mongosh
db.orders.aggregate([
  {
    $project: {
      product: 1,
      quantity: 1,
      lineTotal: {
        $multiply: [
          { $toDecimal: "$price" },
          { $toDecimal: "$quantity" }
        ]
      }
    }
  }
])

// Widget A: 29.99 × 2 = 59.98 (exact)
// Widget C: 0.10 × 10 = 1.00 (exact)

How It Works

Converting both operands to Decimal128 before $multiply ensures the result is exact. With doubles, small values like 0.10 can accumulate rounding errors over many calculations.

Example 3 — Sum Order Totals with $group

Aggregate precise decimal amounts across all orders:

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: null,
      grandTotal: {
        $sum: {
          $multiply: [
            { $toDecimal: "$price" },
            { $toDecimal: "$quantity" }
          ]
        }
      }
    }
  }
])

// grandTotal: Decimal128("107.48") — exact sum

How It Works

$sum over Decimal128 values produces an exact total. This is critical for financial reports where penny-level accuracy matters.

Example 4 — Apply Tax with Decimal Precision

Calculate tax on a subtotal without floating-point drift:

mongosh
db.orders.aggregate([
  {
    $project: {
      product: 1,
      subtotal: {
        $multiply: [
          { $toDecimal: "$price" },
          { $toDecimal: "$quantity" }
        ]
      }
    }
  },
  {
    $addFields: {
      tax: {
        $multiply: [
          "$subtotal",
          { $toDecimal: "0.0825" }
        ]
      }
    }
  },
  {
    $addFields: {
      total: { $add: [ "$subtotal", "$tax" ] }
    }
  }
])

How It Works

Tax rates like 8.25% (0.0825) are stored and multiplied as exact decimals. The final total is subtotal plus tax with no rounding surprises.

Example 5 — Why Not $toDouble?

Compare decimal precision with a classic floating-point example:

mongosh
db.test.aggregate([
  {
    $project: {
      asDouble: {
        $add: [
          { $toDouble: "0.1" },
          { $toDouble: "0.2" }
        ]
      },
      asDecimal: {
        $add: [
          { $toDecimal: "0.1" },
          { $toDecimal: "0.2" }
        ]
      }
    }
  }
])

// asDouble:  0.30000000000000004 (floating-point error)
// asDecimal: Decimal128("0.3")   (exact)

How It Works

Binary floats cannot represent some decimal fractions exactly. Decimal128 stores the value as written, which is why financial apps prefer it.

Bonus — Safe Conversion with $convert

When price strings may be invalid, use $convert with onError:

mongosh
db.orders.aggregate([
  {
    $project: {
      product: 1,
      unitPrice: {
        $convert: {
          input: "$price",
          to: "decimal",
          onError: { $toDecimal: "0" },
          onNull: { $toDecimal: "0" }
        }
      }
    }
  }
])

// "29.99"    → Decimal128("29.99")
// "N/A"      → Decimal128("0") (fallback)
// null/missing → Decimal128("0")

How It Works

$toDecimal errors on invalid strings. $convert with onError lets the pipeline continue with a safe default.

🚀 Use Cases

  • E-commerce pricing — store and calculate product prices, discounts, and totals with penny accuracy.
  • Accounting and invoicing — sum line items, apply tax rates, and generate financial reports.
  • Currency conversion — multiply amounts by exchange rates without floating-point drift.
  • Data import cleanup — parse string prices from CSV/JSON into proper decimal types.
  • Regulatory compliance — meet precision requirements for financial record keeping.

🧠 How $toDecimal Works

1

MongoDB reads the expression

The input resolves from a field path, numeric string, number, or nested expression.

Input
2

Value is parsed to Decimal128

Strings and numbers are converted to exact decimal representation with up to 34 significant digits.

Convert
3

Precise decimal is returned

The Decimal128 value supports exact $add, $multiply, $sum, and comparisons.

Output
=

Exact financial math

Use for totals, tax, and reports where every cent must be correct.

Conclusion

The $toDecimal operator converts values to Decimal128 for high-precision decimal arithmetic in MongoDB aggregation pipelines. It is the right choice for currency, tax, and any calculation where floating-point rounding errors are unacceptable.

For general numeric work where tiny rounding differences are fine, consider $toDouble instead. For conversions with error handling, use $convert. Next in the series: $toDouble.

💡 Best Practices

✅ Do

  • Use $toDecimal for all currency and financial calculations
  • Convert both operands before $multiply or $add
  • Use $convert with onError for messy imported price data
  • Store prices as Decimal128 in new collections when precision matters
  • Test edge cases like 0.10, large totals, and zero values

❌ Don’t

  • Use $toDouble for money when penny accuracy is required
  • Mix Decimal128 and double in the same calculation without converting
  • Assume string prices will auto-convert in arithmetic expressions
  • Forget that invalid numeric strings error with bare $toDecimal
  • Overuse decimals for non-financial data where doubles are sufficient

Key Takeaways

Knowledge Unlocked

Five things to remember about $toDecimal

Use these points when working with precise decimal values in MongoDB.

5
Core concepts
📝 02

{ $toDecimal: x }

One argument.

Syntax
🔢 03

No float error

0.1 + 0.2 = 0.3.

Precision
🛠 04

Money math

Prices, tax, sums.

Usage
05

vs $toDouble

Exact vs float.

Compare

❓ Frequently Asked Questions

$toDecimal converts a value to Decimal128 inside an aggregation pipeline. Decimal128 provides high-precision decimal arithmetic, which is important for financial and currency calculations.
The syntax is { $toDecimal: <expression> }. The expression can be a field reference like "$price", a numeric string, or another numeric expression.
$toDouble uses binary floating point, which can introduce rounding errors (e.g. 0.1 + 0.2). $toDecimal uses Decimal128 for exact decimal representation, making it better for money and accounting.
$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. It does not throw an error for null input.

Continue the Operator Series

Move on to $toDouble for floating-point conversion, or review $convert for flexible type transforms.

Next: $toDouble →

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.

5 people found this page helpful