You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中如何将rust_decimal::Decimal类型正确存入MongoDB

rust_decimal存储到MongoDB的正确方式

直接传值报错的核心原因是bson crate默认没有实现针对第三方rust_decimal::Decimal类型的转换trait;直接传字节转换失败是因为两种Decimal类型的内存布局完全不兼容,并非单纯大小端问题:rust_decimal::Decimal内部采用96位尾数+32位标度/符号的自定义布局,而MongoDB使用的bson::Decimal128遵循IEEE 754-2008 Decimal128标准,采用1位符号+14位指数+113位尾数的布局,直接拷贝字节必然得到错误结果。

推荐方案:启用rust_decimal官方bson适配特性

rust_decimal 1.24.0已经内置了对bson 2.x版本的转换支持,只是默认没有开启,只需要在Cargo.toml中开启对应feature即可:

[dependencies]
mongodb = "2.2.2"
bson = "2.3.0"
rust_decimal = { version = "1.24.0", features = ["bson"] }

开启feature后,rust_decimal会自动实现From<Decimal> for Bson的转换trait,最初写的插入代码不需要做任何修改,运行时会自动将值转换为MongoDB原生Decimal128类型存储,全程无精度损失。

手动转换方案:字符串中转

如果不想引入额外feature,可以通过标准十进制字符串作为中转完成转换,bson::Decimal128内置了字符串解析能力,该路径同样不会丢失精度:

// self.db is of type mongodb::sync::Database
use bson::Decimal128;
use std::str::FromStr;

let decimal = Decimal::new(1, 20);
let bson_decimal = Decimal128::from_str(&decimal.to_string())
    .expect("decimal value exceeds MongoDB Decimal128 valid range");
let order = doc! {"decimal": bson_decimal};
self.db.collection("collection").insert_one(order, None).unwrap();

注意:如果你的Decimal数值超出了IEEE 754 Decimal128的可表示范围,字符串解析会返回错误,需要提前做范围校验,或者选择将值存为字符串/二进制等其他类型。

内容的提问来源于stack exchange,提问作者Dipsy Shrimp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 04:15:51