MongoDB - What about Decimal type of value?

Viewed 56945

I am currently learning and applying MongoDB for a small financial related project.


When I read MongoDB in Action, it says:

The only other issue that commonly arises with BSON numeric types is the lack of decimal support. This means that if you’re planning on storing currency values in MongoDB, you need to use an integer type and keep the values in cents.


My financial related product will involve some currency values, but I am little bit confused or worried about the above statement. Here are my questions:

  1. Can I use double for those currency values in my project?
  2. What will happen or is the consequences if I directly use double for them?
  3. If decimal type is an must-have thing for financial product, is that a bad idea to use MongoDB?
  4. What does it mean you need to use an integer type and keep the values in cents? Does it mean that if I am going to store 1.34 dollars, then I should store 134 cents?
7 Answers

When you don't want to store currency as cent-values, you could store a currency of $1.34 as an object like this:

{
    major: 1,
    minor: 34,
    currency: "USD"
}

Doing any math with objects like this would not be easy and would not use commercial rounding rules. But you shouldn't do any business logic on the database anyway, especially not when it's a "dumb" database like MongoDB.

What you should be doing is serialize/deserialize these objects from/to a Money class in your application which implements the basic currency math operations respecting the rounding rules and throws an exception when you try to do an operation with different currency units ($12.34 + 14.95€ = error - must convert one currency to the other currency first by providing an exchange rate).

NodeJS Users:

Note that if using NodeJS, you don't use NumberDecimal(string) directly, you instead use Decimal128.fromString(string).

References:

Example:

const Decimal128 = require('mongodb').Decimal128

usersCollection.findOneAndUpdate({_id: ObjectID(this.data.userId), "myWells.wellId": ObjectID(this.data.wellId)},
  { 
    $set: { "myWells.$.interest": Decimal128.fromString(this.data.interest) }
  }
)
Related