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

使用doc!宏传u128属性时报`Bson: From<u128>`不满足如何解决

报错根因

MongoDB BSON 协议没有提供与 Rust u128 类型对应的原生标量类型:u32、i64 可以直接映射到 BSON 的 32 位整数、64 位整数类型,而 u128 超出了 BSON 原生整数的表示范围,序列化时无法匹配对应类型,因此触发报错。


解决方案

根据你的业务场景可选择以下任意一种方案:

方案1:序列化为 BSON Binary 类型(推荐)

该方案保留数值的二进制特性,同时支持精确匹配、范围查询,无精度损失:

use mongodb::bson::{Binary, doc};
use mongodb::bson::spec::BinarySubtype;

pub async fn read_foo(client: mongodb::Client, key: u128) -> Option<mongodb::bson::Document> {
    // 统一使用大端序转换为字节数组,读写逻辑保持一致即可
    let key_binary = Binary {
        subtype: BinarySubtype::Generic,
        bytes: key.to_be_bytes().to_vec()
    };

    client
        .database("db")
        .collection("col")
        .find_one(doc! {"key": key_binary}, None)
        .await
        .expect("Could not connect to database")
}

注意:写入数据时也需要用相同的端序逻辑将 u128 转换为 Binary 类型再入库,保证读写匹配。

方案2:转为字符串存储(适合仅需精确匹配的场景)

如果不需要对 key 做数值范围查询,该方案实现成本最低:

pub async fn read_foo(client: mongodb::Client, key: u128) -> Option<mongodb::bson::Document> {
    client
        .database("db")
        .collection("col")
        .find_one(doc! {"key": key.to_string()}, None)
        .await
        .expect("Could not connect to database")
}

方案3:serde 自定义序列化规则

如果你使用 serde 做 BSON 序列化/反序列化,可以给结构体字段添加自定义序列化逻辑,避免每次手动转换:

use serde::{Serialize, Deserialize};
use mongodb::bson::Binary;
use mongodb::bson::spec::BinarySubtype;

// 你的业务数据结构体
#[derive(Serialize, Deserialize)]
struct BusinessDoc {
    #[serde(with = "u128_bson")]
    key: u128,
    // 其他字段省略
}

mod u128_bson {
    use super::*;
    use serde::{Serializer, Deserializer, Deserialize};

    pub fn serialize<S>(val: &u128, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        Binary {
            subtype: BinarySubtype::Generic,
            bytes: val.to_be_bytes().to_vec(),
        }.serialize(serializer)
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<u128, D::Error>
    where
        D: Deserializer<'de>,
    {
        let bin = Binary::deserialize(deserializer)?;
        let bytes: [u8; 16] = bin.bytes.try_into().map_err(serde::de::Error::custom)?;
        Ok(u128::from_be_bytes(bytes))
    }
}

内容的提问来源于stack exchange,提问作者0xba1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:36:04