Need to store high precision decimal values in Mon

2020-04-04 10:43发布

I have little experience with MongoDB. I am usual working on large scale SQL server DBs.

MongoDB only supports double and there is no decimal. The C# driver serializes decimals as strings.

  • What functionality do I miss if I store decimals as strings in MongoDB?

  • Is there a way to set a default serialization of decimals as double (AllowTruncation) without having to put an Attribute on each property?

  • What do I lose in precision if I used Bson double?

Thanks for your help!

UPDATE

I have an existing application model that uses decimals in C#. I want to use MongoDB as a new DB layer and change as little in the existing app as possible. Thats why I am looking for a way to map decimals in C# to double in MongoDB.
I understand that I loose precision and would have to analyze the side effects of it. My only remaining question is to know if there is a way to set a default serialization of decimals as double.

Thanks again. Great answers and comments so far.

2条回答
爷、活的狠高调
2楼-- · 2020-04-04 11:10

As of Mongodb 3.4 and the 2.4 Mongodb C# driver, decimal types are supported.

The properties of your document must have the [BsonRepresentation(BsonType.Decimal128)] attribute found in the MongoDB.Bson.Serialization.Attributes namespace.

this will map to "YourDecimalValue" : NumberDecimal("100.0000") in MongodDB. Robomongo supports the new decimal type from version 1.1 Beta.

查看更多
ゆ 、 Hurt°
3楼-- · 2020-04-04 11:23

I will answer your question partially (because I do not know much about C#).

So what will you lose if you will store decimals as strings.

  • your numbers on average would weight more (each double number cost 8 bytes to store which means that every string that has more then 8 chars will weight more). Because of these your indexes (if they will be built on this field would grow)
  • you will not be able to use operators which takes numbers as arguments $inc, $bit, $mod, $min, $max and in 2.6 version $mul. (May be I forgot something)
  • you will not be able to compare numbers (may be '1.65' and '1.23' is comparable as a string, but definitely not numbers with e and minuses somewhere in between). Because of this operations which build on top of comparison like $sort, and all these $gte, $gt, $lte, $lt will not work correctly.

What will you lose in precision if you store decimal as double:

  • based on this, Decimal in C# has 28-29 significant digits, whereas looking at my first link and checking the spec for double precision you see that it has 15-17 significant digits. This is basically what you will lose
  • another really important thing which people sometimes forget when dealing with double floats is illustrated below:

.

db.c.insert({_id : 1, b : 3.44}) 
db.c.update({_id : 1},{$inc : {b : 1}})
db.c.find({b: 4.44})  // WTf, where is my document? There is nothing there

Regarding the 2-nd subquestion:

Is there a way to set a default serialization of decimals as double (AllowTruncation) without having to put an Attribute on each property?

I do not really understood it, so I hope someone would be able to answer it.

查看更多
登录 后发表回答