如何在使用 Rust Mongo 驱动程序原型时将 chrono::DateTime 字段序列化为 ISODate?

9

当使用Rust Mongo driver prototype时,结构体中的日期时间字段被序列化为String而不是ISODate。我该如何让这些字段保存为ISODate

use chrono::{DateTime, Utc};
use mongodb::oid::ObjectId;
use mongodb::{
    coll::Collection, db::Database, db::ThreadedDatabase, error::Error, Client, ThreadedClient,
};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug)]
struct Person {
    pub _id: ObjectId,
    pub date: DateTime<Utc>,
}

fn main() {
    let client = Client.with_uri("mongodb://localhost:27017").unwrap();
    let p = Person {
        _id: ObjectId::new().unwrap(),
        date: Utc::now(),
    };
    let document = mongodb::to_bson(p).unwrap().as_document();
    if document.is_some() {
        client
            .db("my_db")
            .collection("mycollection")
            .insert_one(document, None)
            .unwrap();
    }
}

在查询数据库时,记录包含一个日期字符串(使用ISO格式);我预期它应该是一个ISODate

1
尝试使用UtcDateTime - Stargateur
是的,我知道UtcDatetime可以工作。然而,就像对于i32i64String一样,我不必在我的结构体中使用bson::Bson::Stringbson::Bson::I32bson::Bson::I64,序列化器应该透明地处理转换。添加结构字段的变体也将是可接受的解决方案。 - nngg
这是不可能的,mongodb 无法为 DateTime 实现 Serialize,需要一个包装器,而且看起来 bson 已经有了并且共享了它。为什么不使用它呢? - Stargateur
官方驱动程序也有同样的问题。如果我放置一个序列化的结构体,它会写入一个字符串,但是当我使用带有Utc的文档进行更新时,它会写入无法反序列化的数据。 - DenisKolodin
2个回答

4

使用版本为2.0.0-beta.1的mongodb和bson包

在Cargo.toml文件中,添加名为chrono-0_4的功能(feature):

bson = { version = "2.0.0-beta.1", features = ["chrono-0_4"] }

然后使用注释标记您的字段,例如:

use chrono::{DateTime, Utc};

#[serde(with = "bson::serde_helpers::chrono_datetime_as_bson_datetime")]
date: DateTime<Utc>,

1
当日期为 Option<DateTime<Utc>> 时,您该如何处理? - Clark McCauley
1
@ClarkMcCauley 我自己写了一个包装器 https://gist.github.com/ImTheSquid/b5f34c39c5c4a7760b3917c394b9ec07 - ImTheSquid

4
你可以使用serde_helpers将反序列化为ISO字符串。 https://docs.rs/bson/1.2.2/bson/serde_helpers/index.html
use mongodb::bson::DateTime;
use mongodb::bson::serde_helpers::bson_datetime_as_iso_string;

#[derive(Serialize, Deserialize, Clone, Debug)]
struct Person {
    pub _id: ObjectId,
    #[serde(with = "bson_datetime_as_iso_string")]
    date: DateTime,
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接