I am developing an ecommerce site in Lift with MongoDB
I need to store some data for product prices
My question is this:
What field type should I use in MongoDB if I want to store data type BigDecimal
In mapper is a field of type: MappedDecimal, but
in net.liftweb.mongodb.record.field no equivalent
How I can to store this information?
Thank you all for your attention and help
As of MongoDB v2.6 there is no fixed-places decimal type. The data has to be saved in a field of a different type and the application must perform translation everytime.
Potentially the intermediary libs could do this translation instead of your application. I guess net.liftweb.record does not.
If a double type would suffice for the field(s) in question, I recommend changing to that for simplicity. But assuming you are using BigDecimal for good reasons, there are well-known workarounds. These are:
(1) Store it as a string. You can have any arbitrary precision. But sorting or querying for exact value matches will only work if you pad the left side with zeroes to a fixed length every time. Even then positive and negative numbers are two different ranges sorting-wise. The negatives need to be sorted in reverse to have correct numerical sorting. An example of the order MongoDB will naturally return these zero-padded string numbers:
I believe the BigDecimal type has a constructor from a string value, so this might be the easiest to implement in your application's translation function.
(2) Store it as a shifted long (Int64). Sorting works, less disk space is used, no problems with negative v.s. positive. Requires shifting the values up by a fixed multiple which makes a bit unreadable when looking at the database directly. The precision has to be fixed to be the same for all the values in the whole collection- OK for financial use cases; not OK for some scientific use cases.
(3) Store as a pair of numbers, one for either side of the decimal point. Sorting requires a extra little work. If using Int32 numbers the precision will be limited to 9 digits either side of the decimal. Looking at two columns in the db instead of one is a little more work of course.
For a Scala code example I found the Reactive driver for MongoDB project has documented three serialization workarounds for BigDecimal. The first uses double; the latter two take yet another approach- create a whole sub-document for BigDecimal value. Trying to query values wrapped in sub-documents would be tricky I suspect.
Another real-life case from an Ebay dev team blog (Morphia/Java)
P.S. maybe MongoDB will add a decimal type in the future. There is a open feature request for it that you can watch/upvote - https://jira.mongodb.org/browse/SERVER-1393