Skip to content
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

How to serialize a hashmap into BSON? #1083

Closed
Bryson14 opened this issue Apr 18, 2024 · 5 comments
Closed

How to serialize a hashmap into BSON? #1083

Bryson14 opened this issue Apr 18, 2024 · 5 comments

Comments

@Bryson14
Copy link

Using rust 1.77 and mongodb 2.8.2

How can i serialize a hashmap of strings into mongodb as a Tag Based Aquisition System.

For example:

	pub fn file_to_bson(&self) -> Document {
		let map : HashMap<String, String> = HashMap::new();
		let document = doc! {"tags": map};
		document
	}
	```
	
This throws the error 

the trait bound `Bson: From<HashMap<std::string::String, std::string::String>>` is not satisfied
the following other types implement trait `From<T>`:
  <Bson as From<bool>>
  <Bson as From<i32>>
  <Bson as From<i64>>
  <Bson as From<u32>>
  <Bson as From<f32>>
  <Bson as From<f64>>
  <Bson as From<chrono::datetime::DateTime<T>>>
  <Bson as From<bson::Binary>>
and 21 others
required for `HashMap<std::string::String, std::string::String>` to implement `Into<Bson>`

I wanted to use this as a system to save tags and values for a docuemnt in MongoDB. These tags would be used later on to search for items belonging to tags or groups. Is this possible?
@isabelatkinson
Copy link
Contributor

isabelatkinson commented Apr 18, 2024

Hey @Bryson14, thanks for opening this issue! You should be able to use this FromIterator implementation to convert from a hashmap to bson, but it'll take a few steps to get there.

First, the FromIterator implementation only works for maps over (String, Bson) pairs, so you'll need to convert your map to use Bson values. If you already have an existing (String, String) map, you can map the strings into Bson like so:

let string_map: HashMap<String, String> = todo!(); // your map goes here
let bson_map: HashMap<String, Bson> = string_map
    .into_iter()
    .map(|(key, value)| (key, value.into())) // Bson implements From<String>
    .collect();

Or, if possible, you can just construct your map with Bson::String values rather than regular Strings.

Second, you'll need to convert your map into a Document before you can pass it into the doc macro, as doc only accepts types that can be converted directly into Bson. This is where FromIterator comes into play:

use std::iter::FromIterator;

let map_doc = Document::from_iter(bson_map);

Putting it all together:

let map_doc = Document::from_iter(string_map.into_iter().map(|(key, value)| (key, value.into())));
let document = doc! { "tags": map_doc };

That said, passing a map like yours directly into the doc macro seems like a reasonable use case. I filed RUST-1916 to discuss this further with the team.

@Bryson14
Copy link
Author

That looks great! after I send that, I realized I could do something like this also:

let map : HashMap<String, Option<String>> = HashMap::new();
        let valid = bson::to_bson(&map).is_err(e)?;
        let document = doc! {"tags": valid};

This is fine for serializing. But for deserializng the data as is coming from the database as a bson::Document, I haven't tested if that would work, or if more work is needed for that.

@isabelatkinson
Copy link
Contributor

You should be able to use from_document to deserialize from a Document into your HashMap type.

Copy link

There has not been any recent activity on this ticket, so we are marking it as stale. If we do not hear anything further from you, this issue will be automatically closed in one week.

@github-actions github-actions bot added the Stale label Apr 27, 2024
Copy link

github-actions bot commented May 5, 2024

There has not been any recent activity on this ticket, so we are closing it. Thanks for reaching out and please feel free to file a new issue if you have further questions.

@github-actions github-actions bot closed this as completed May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants