当前位置: 首页 > 知识库问答 >
问题:

将存储为BigDecimal类型的数字值与MongoDB中的Spring数据MongoDB进行排序

慕健
2023-03-14

我正在学习Spring Data MongoDB的教程(https://spring.io/guides/tutorials/data/2/).在本教程中,成本的类型是BigDecimal,如下所示,并在MongoDB中存储为“字符串”。所以,当我试图通过成本域的升序排序得到排序结果时,我得到了一个错误的结果。

我发现使用BigDecimal类是计算的最佳方式。但是,如果我在MongoDB中使用Spring数据MongoDB将数字保存为BigDecimal类型,它将被保存为字符串类型,我将得到错误的排序结果,如本教程所示。

为了精确起见,我能做些什么来获得正确的数字排序结果?你能帮我解决这个问题吗?提前非常感谢。

例如,

1.

@Document(collection = "menu")
public class MenuItem {
  @Id
  private String id;

  @Field("itemName")
  @Indexed
  private String name;
  private BigDecimal cost;

2.

MenuItem item = new MenuItem();
item.setDescription("Peanutty Noodles, perfect for every occasion.");
item.setName("Yummy Noodles");
item.setCost(new BigDecimal("52.99"));


MenuItem item = new MenuItem();
item.setDescription("Rice, Egg Fried");
item.setName("Yummy Rice");
item.setCost(new BigDecimal("211.99")); 

3.

db.menu.find排序

{"_id": ObjectId("53e982f0300475a4fbab8c32"),"_class":"com.yummynoodlebar.persistence.domain.MenuItem","itemName":"Yummy Rice","描述":"米饭,鸡蛋煎","食材": [ { "名称":"鸡蛋","描述":"鸡蛋" }, { "名称":"米饭","描述":"直白米" } ], "成本":"211.99","minutesTo准备": 0}

{u id:ObjectId(“53E982F030475A4FBAB8C33”),“_类”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName:“美味大米”,“description:”大米,煎蛋”,“配料”:[{“名称”:“鸡蛋”,“描述”:“鸡蛋”},{“名称”:“大米”,“描述”:“直白大米”}],“成本”:“211 99”,“分钟准备”:0}

{“_id”:ObjectId(“53E982F030475A4FBAB8C2F”),“_类”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“美味面条”,“描述”:“花生面条,适合各种场合。”,“配料”:[{“名称”:“花生”,“描述”:“坚果”},{“名称”:“鸡蛋”,“描述”:“用于面条”},{“名称”:“面条”,“描述”:“脆、可爱的面条”}],“成本”:“52.99”,“分钟准备”:0}

{“_id”:ObjectId(“53E982F030475A4FBAB8C30”),“_类”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“美味面条”,“描述”:“花生面条,适合各种场合。”,“配料”:[{“名称”:“花生”,“描述”:“坚果”},{“名称”:“鸡蛋”,“描述”:“用于面条”},{“名称”:“面条”,“描述”:“脆、可爱的面条”}],“成本”:“52.99”,“分钟准备”:0}

{“_id”:ObjectId(“53E982F030475A4FBAB8C31”),“_类”:“com.yummynoodlebar.persistence.domain.MenuItem”,“itemName”:“美味面条”,“描述”:“花生面条,适合各种场合。”,“配料”:[{“名称”:“鸡蛋”,“描述”:“用于面条”},{“名称”:“花生”,“描述”:“坚果”},{“名称”:“面条”,“描述”:“脆、可爱的面条”}],“成本”:“52.99”,“分钟准备”:0}

共有3个答案

督德明
2023-03-14

如果您正在处理金钱问题,而“成本”看起来是这样的,那么在代码中使用Money类。钱将携带金额和货币。Money有方法以大十进制等形式获取金额。MongoDB中的Money保持如下丰富形状:

{成本:{amt: 21199,ccode:"USD"}}

所有同种货币的数字运算(eq、gt、it等)都精确工作。无论如何,你不能在数据库中进行跨货币比较,因为汇率是动态的。

http://www.moschetti.org/rants/mongomoney.html

姬捷
2023-03-14

不幸的是,BigDecimal本机不受MongoDB支持。这就是为什么我们在默认情况下将其转换为Strings。

对于更多的数字处理,特别是如果你处理价格或类似的,我们通常建议而是存储双倍,并将它们转换为BigDecimals,以便直接在域对象中进行算术操作。

干善
2023-03-14

自3.4版以来,MongoDB通过新的十进制数据类型(decimal128)添加了对“BigDecimal”的支持。然而,Spring data仍然默认将JavaBigDecimal映射到MongoDB字符串(我猜这是为了向后兼容)。好消息是默认映射可以简单地通过在Spring Boot应用程序中注入一个CustomConversion来覆盖,如下所示:

@Bean
CustomConversions customConverions() {
  Converter<Decimal128, BigDecimal> decimal128ToBigDecimal = new Converter<Decimal128, BigDecimal>() {
    @Override
    public BigDecimal convert(Decimal128 s) {
      return s==null ? null : s.bigDecimalValue();
    }
  };

  Converter<BigDecimal, Decimal128> bigDecimalToDecimal128 = new Converter<BigDecimal, Decimal128>() {
    @Override
    public Decimal128 convert(BigDecimal s) {
      return s==null ? null : new Decimal128(s);
    }
  };

  return new CustomConversions(Arrays.asList(decimal128ToBigDecimal, bigDecimalToDecimal128));
}

请查看这篇文章以获得更详细的信息,甚至是一个完整的例子。

 类似资料:
  • 每当我在这个集合中保存一些数据时,我就声明了一个类LoanDetails和一个包含BigDecimal类型loanAmount的字段 它以字符串形式存储在mongo db数据库中 我试图在loanAmount字段上添加注释

  • 我想知道是否有任何机制可以在Spring Data MongoDB存储库中使用带有注释的?我希望能收到我所拥有的文件数量,而不必获取所有文件。 基本上,这在Java中相当于:

  • 主要内容:Object ID,Timestamps,Date下表中列举了 MongoDB 中常用的几种数据类型: 数据类型 描述 String 字符串类型,是最常用的数据类型,不过在 MongoDB 中,只有 UTF-8 编码的字符串才是合法的 Integer 整型,用于存储数值。根据您使用服务器的不同,整型可以分为 32 位或 64 位两种 Boolean 布尔型,用于存储布尔类型的值(true/false) Double 双精度浮点型,用于存储浮点型(

  • 我想使用SpringBoot和SpringDataMongoDB开发一个小测试应用程序。因此,在本例中,我使用默认配置(如localhost:27017/test-database),并尝试遵循spring指南(https://spring.io/guides/gs/accessing-data-mongodb/). 我按如下方式启动我的应用程序: DummyClass如下所示: 当project

  • 我试图使用Spring Data MongoDB(2.2.3-发行版)将Kotlin的(v1.3.61)内联类存储到MongoDB中,但到目前为止还没有成功。这是设置: 而且 stacktrace相当模糊,但异常发生在中,并且是构造函数的一部分,因此问题可能就在那里。 接下来是检查类的字节代码: 这是来自Spring源代码的的相关行221: 我完全不懂字节码,但其中一个可能会马上看到问题。 我还尝

  • 我需要使用spring@Cacheable注释缓存对MongoDB的调用: 不幸的是,使用@Cacheable注释接口中的任何方法都会导致以下异常: 我正在寻找一种方法来缓存对DB的调用(这相当昂贵)。有什么想法吗?