-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serialize issue of ObjectId #62
Comments
@surfingtomchen are you getting an actual error somewhere in your code? |
how to convert to
I tried flatten of serde, but it shows
and can not rename after flattern |
@surfingtomchen I understand. What I am trying to communicate however is that the representation you are seeing is correct. When you encode a BSON ObjectId as extended JSON, as described here, that is what you get. What you are seeing is an issue with this BSON library (https://github.com/mongodb/bson-rust). There is probably lots more discussion on this very topic over there. HOWEVER, an immediate solution would be to create a struct which holds your That should resolve your issue. If you think changes are needed to the BSON lib, please open an issue there. Cheers! |
@surfingtomchen I think you might be misunderstanding the output when you're printing a BSON document. Try running the following code in a clean Rust project: [dependencies]
mongodb = "1.1.1"
serde = { version = "1.0.116", features = ["derive"] }
tokio = { version = "0.2.22", features = ["macros", "rt-threaded"] } use mongodb::{bson::oid::ObjectId, Client};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)]
struct User {
/// The ID of the model.
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
id: Option<ObjectId>,
nick: String,
}
#[tokio::main]
async fn main() {
let client = Client::with_options(Default::default()).unwrap();
let coll = client.database("foo").collection("bar");
let user = User {
id: Some(ObjectId::new()),
nick: "saghm".into(),
};
coll.insert_one(mongodb::bson::to_document(&user).unwrap(), None)
.await
.unwrap();
let user = coll.find_one(None, None).await.unwrap().unwrap();
println!("{:#?}", user);
} The output of this short program will show that the ObjectId is correctly getting round-tripped as a bson ObjectId value:
The confusion you're having stems from the fact that our |
@thedodd @saghm Thank you for your clarification. I totally understand and agree with you why the ObjectId should be displayed as Extended JSON with $oid inside it to have Mongo read it properly. I guess maybe current issue should not be described as bug but a feature request. Because when I use the mongoose for Node.js, if I defined id as ObjectId, mongoose will automatically displayed as string once output it to the http response. That's why @thedodd suggest me to use another structure to store the value as String. It will solve the problem but have a little bit inconvience. I believe Wither plays the same role in Rust as Mongoose to Node.js. Please consider the feature request, thanks. |
@surfingtomchen good, glad we were able to find an immediate solution. For a long-term change as you mentioned, I think it would be best to open an issue for this in the BSON crate, as that is where the type lives. I leave that up to you. It may need some design, perhaps a special function ... not sure. Let me know if there is anything else to discuss. Otherwise, mind closing the issue? |
Yes, the issue will be closed |
@surfingtomchen the approach I am using is this one: use serde::Serializer;
use wither::bson::oid::ObjectId;
pub fn serialize_object_id<S>(object_id: &Option<ObjectId>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match object_id {
Some(ref object_id) => serializer.serialize_some(object_id.to_string().as_str()),
None => serializer.serialize_none()
}
} #[derive(Debug, Model, Serialize, Deserialize)]
pub struct Foo {
#[serde(
rename = "_id",
skip_serializing_if = "Option::is_none",
serialize_with = "serialize_object_id"
)]
pub id: Option<ObjectId>,
} I am not sure if this is the best approach but you can try it out. |
I have a very simple structure, after save to the db and return back in a api call, there is a
$oid
in the _id field. How to serialize it only with _id?Thanks.
The text was updated successfully, but these errors were encountered: