Как мне сериализовать поля chrono ::DateTime как ISODate при использовании прототипа драйвера Rust Mongo?

#mongodb #rust #bson #serde

#mongodb #Ржавчина #бсон #serde

Вопрос:

Поля даты и времени в структурах сериализуются в String s вместо ISODate s при использовании прототипа драйвера Rust Mongo. Как мне сделать так, чтобы поля были сохранены как 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); Я ожидал, что это будет an ISODate .

Комментарии:

1. попробуйте использовать UtcDateTime

2. Да, я знаю, что UtcDatetime это сработало бы. Однако, как и для i32 , i64 , или String , мне не нужно использовать bson::Bson::String или bson::Bson::I32 или bson::Bson::I64 в моих структурах, сериализатор должен позаботиться о преобразовании прозрачно. Добавление вариантов к полям структуры также было бы приемлемым решением.

3. Это невозможно mongodb реализовать Serialize , для DateTime них нужна оболочка, и похоже bson , что она есть и ею можно поделиться. Почему бы не использовать его?

4. У официального драйвера та же проблема. Если я помещаю сериализованную структуру, она записывает строку, но когда я обновляю ее с помощью doc, Utc она записывает данные, которые нельзя десериализовать 😢

Ответ №1:

Вы можете выбрать десериализацию в виде строки ISO с помощью serde_helpers .

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,
}
 

Ответ №2:

С ящиками mongodb и bson в версии 2.0.0-beta.1

В Cargo.toml добавьте функцию chrono-0_4:

 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>,