0

我正在使用 MongoDB 在 Lift 中开发电子商务网站

我需要存储一些产品价格数据

我的问题是这样的:

如果我想存储数据类型 BigDecimal,我应该在 MongoDB 中使用什么字段类型

在 mapper 中是一个类型的字段:MappedDecimal,但是

在 net.liftweb.mongodb.record.field 中没有等价物

我怎样才能存储这些信息?

谢谢大家的关注和帮助

4

1 回答 1

6

从 MongoDB v2.6 开始,没有固定位数的小数类型。数据必须保存在不同类型的字段中,并且应用程序必须每次都执行翻译。

中介库可能会代替您的应用程序进行此翻译。我猜 net.liftweb.record 没有。

如果 double 类型足以满足相关字段的需求,我建议为简单起见更改为该类型。但是假设您出于充分的理由使用 BigDecimal,则有一些众所周知的解决方法。这些是:

(1)将其存储为字符串。您可以具有任意精度。但是,只有在每次将左侧填充零到固定长度时,才能对精确值匹配进行排序或查询。即使这样,正数和负数也是两个不同的排序范围。负数需要反向排序才能进行正确的数字排序。MongoDB 的命令示例自然会返回这些零填充的字符串数字:

"-0000054321.9876"
"-0000100322"
"0000054321.9876"
"0000100322"

我相信 BigDecimal 类型具有来自字符串值的构造函数,因此这可能是在应用程序的翻译函数中最容易实现的。

(2)将其存储为移位的 long (Int64)。排序工作,使用更少的磁盘空间,负与正没有问题。需要将值向上移动一个固定的倍数,这在直接查看数据库时有点不可读。对于整个集合中的所有值,精度必须固定为相同 - 对于金融用例可以;不适用于某些科学用例。

(3)存储为一对数字,小数点两边各一个。排序需要额外的一点工作。如果使用 Int32 数字,则精度将限制为小数点两侧的 9 位。当然,查看数据库中的两列而不是一列需要更多的工作。

对于 Scala 代码示例,我发现 MongoDB 项目的 Reactive 驱动程序记录了 BigDecimal 的三个序列化解决方法。第一个使用双精度;后两者采用另一种方法——为 BigDecimal 值创建一个完整的子文档。我怀疑尝试查询包含在子文档中的值会很棘手。

另一个来自 Ebay 开发团队博客的真实案例(Morphia/Java)


PS 可能 MongoDB 以后会增加十进制类型。有一个开放的功能请求,您可以观看/投票 - https://jira.mongodb.org/browse/SERVER-1393

于 2015-01-16T06:10:52.140 回答