Mongodb rust driver find one by id

Hi,
I am trying to connect my actix web server with my mondob database and tried to implement a find by Id and simple insert endpoint. The insertion works but it inserts 2 id fields (id and _id) is there any way to specify my UUID as the only id to be used for MongoDB when inserting. And how do I query by Id with this driver I tried a lot of things and nothing seems to work. Code for the repository functions below. Generic T should be replaced with NewsArticle for example. Thanks for the help!

pub struct MongDbRepository<T> {
    pub url: String,
    pub collection: Collection<T>,
}

impl<T> MongDbRepository<T> {
    pub fn new(url: String, collection: Collection<T>) -> Self {
        MongDbRepository { url, collection }
    }

    pub async fn insert_one(
        &self,
        to_insert: &T,
    ) -> Result<InsertOneResult, mongodb::error::Error>
    where
        T: Serialize,
    {
        let result = self.collection.insert_one(to_insert, None).await;

        result
    }

    pub async fn query_one(&self, id: &Uuid) -> Option<T>
    where
        T: DeserializeOwned + Unpin + Send + Sync,
    {
        let bson_id = mongodb::bson::uuid::Uuid::from_bytes(id.into_bytes());

        let query_result = self
            .collection
            .find_one(Some(doc! {"_id": bson_id}), None)
            .await
            .expect("Query result not found");

        query_result
    }
}

#[derive(Deserialize, Serialize)]
pub struct NewsarticleDto {
    pub name: String,   
}

#[derive(Serialize, Clone, Deserialize)]
pub struct Newsarticle {
    pub id: Uuid,
    pub name: String,
}

impl Display for Newsarticle {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{} {}", self.id, self.name)
    }
}

impl From<NewsarticleDto> for Newsarticle {
    fn from(article: NewsarticleDto) -> Self {
        Newsarticle {
            id: Uuid::new_v4(),
            name: article.name,
        }
    }
}

Hi @Thomas_Mages -

To accomplish this, you can just rename the id field in your Newsarticle struct to _id. If there is already a field named _id present in the document, the driver won’t add one. Currently the driver adds one for you because MongoDB requires there is some field named _id.

Alternatively, if you need the field to be named id on your Rust type for some reason you could use the Serde rename attribute to specify that the field should be serialized/deserialized to/from BSON under the name _id.

I think the problem with your query_one code sample is that you are trying to filter on the _id field but using the UUID value that is stored under id, not _id. If you make the change I suggest above so that the UUID is stored under the name _id then I think your code should work as expected.

I also want to point out that rather than round-tripping through bytes to create a bson::uuid::Uuid from a Uuid you could use one of the conversion helper functions provided by the driver: either from_uuid_0_8 if you are using v0.8 of the uuid crate, or from_uuid_1 if you are using v1 of the uuid crate. (Each of these will require turning on a corresponding feature, as noted in the linked docs.)