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