{"id":20519444,"url":"https://github.com/withsecurelabs/mongo-rs","last_synced_at":"2025-08-16T13:34:05.234Z","repository":{"id":48918710,"uuid":"323413005","full_name":"WithSecureLabs/mongo-rs","owner":"WithSecureLabs","description":"A higher-level wrapper on top of the official bson \u0026 mongodb crates.","archived":false,"fork":false,"pushed_at":"2024-12-03T15:11:08.000Z","size":114,"stargazers_count":16,"open_issues_count":5,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-11T00:05:26.027Z","etag":null,"topics":["countercept","mongodb","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WithSecureLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-21T18:09:34.000Z","updated_at":"2024-12-13T10:05:27.000Z","dependencies_parsed_at":"2024-11-15T06:14:54.309Z","dependency_job_id":"ca6a2244-171d-45db-a0bc-9ad215bcc601","html_url":"https://github.com/WithSecureLabs/mongo-rs","commit_stats":null,"previous_names":["countercept/mongo-rs"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithSecureLabs%2Fmongo-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithSecureLabs%2Fmongo-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithSecureLabs%2Fmongo-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WithSecureLabs%2Fmongo-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WithSecureLabs","download_url":"https://codeload.github.com/WithSecureLabs/mongo-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248809046,"owners_count":21164896,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["countercept","mongodb","rust"],"created_at":"2024-11-15T22:13:46.761Z","updated_at":"2025-04-14T02:10:47.436Z","avatar_url":"https://github.com/WithSecureLabs.png","language":"Rust","readme":"# Mongo\n\n[![crates.io](https://img.shields.io/crates/v/mongod.svg)](https://crates.io/crates/mongod)\n[![Documentation](https://docs.rs/mongod/badge.svg)](https://docs.rs/mongod)\n\nA higher-level wrapper on top of the official bson \u0026 mongodb crates.\n\n## Overview\n\nThe `mongod` crate is an unofficial higher-level wrapper that aims to make the bson \u0026 mongodb crates a little bit more rust-like.\n\nProvides the following:\n- builder style queries\n- clients with async/non-async support\n- derives for `Bson` \u0026 `Mongo` to help with BSON type conversion and implentation of traits provided by this crate\n- strong opinions through the use of traits\n\n## Example\n\n```toml\nfutures = \"0.3\"\nmongod = { version = \"0.3\", features = [\"derive\"] }\ntokio = { version = \"1.0\", features = [\"full\"] }\n```\n\n```rust\nuse futures::stream::StreamExt;\nuse mongod::{Bson, Mongo};\nuse mongod::{AsFilter, AsUpdate, Collection, Comparator, Updates};\n\n#[derive(Debug, Bson, Mongo)]\n#[mongo(collection = \"users\", field, filter, update)]\npub struct User {\n  pub name: String,\n  pub age: Option\u003cu32\u003e,\n}\n\n#[tokio::main]\nasync fn main() {\n  // Create and async client\n  let client = mongod::Client::new();\n\n  // Insert a user into the users collection\n  let user = User { name: \"foo\".to_string(), age: None };\n  let oid = client.insert_one::\u003cUser\u003e(user).await.unwrap();\n  println!(\"{:?}\", oid);\n\n  // Fetch all users in the users collection\n  let mut cursor = client.find::\u003cUser, _\u003e(None).await.unwrap();\n  while let Some(res) = cursor.next().await {\n      if let Ok((id, user)) = res {\n          println!(\"{} - {:?}\", id, user);\n      }\n  }\n\n  // Update the user\n  let mut filter = User::filter();\n  filter.name = Some(Comparator::Eq(\"foo\".to_owned()));\n  let mut update = User::update();\n  update.age = Some(Some(0));\n  let updates = Updates {\n      set: Some(update),\n      ..Default::default()\n  };\n  let updated = client.update::\u003cUser, _, _\u003e(filter, updates).await.unwrap();\n  println!(\"updated {} documents\", updated);\n\n  // Delete all users\n  let deleted = client.delete::\u003cUser, _\u003e(None).await.unwrap();\n  println!(\"delete {} documents\", deleted);\n}\n```\n\n## Client\n\n### Async\n\nThe default client is async and provides convenience functions over those exposed by the mongodb driver.\n\nExample: see above.\n\n### Blocking\n\nNot everything should be async and for that reason a blocking client is provided that can be used at the same time as the async client.\n\n```toml\nmongod = { version = \"0.3\", features = [\"blocking\", \"derive\"] }\n```\n\n```rust\nuse mongod::{Bson, Mongo};\nuse mongod::{AsFilter, AsUpdate, Collection, Comparator, Updates};\n\n#[derive(Debug, Bson, Mongo)]\n#[mongo(collection = \"users\", field, filter, update)]\npub struct User {\n  pub name: String,\n  pub age: Option\u003cu32\u003e,\n}\n\nfn main() {\n  // Create and async client\n  let client = mongo::blocking::Client::new();\n\n  // Insert a user into the users collection\n  let user = User { name: \"foo\".to_string(), age: None };\n  let oid = client.insert_one::\u003cUser\u003e(user).unwrap();\n  println!(\"{:?}\", oid);\n\n  // Fetch all users in the users collection\n  let mut cursor = client.find::\u003cUser, _\u003e(None).unwrap();\n  while let Some(res) = cursor.next() {\n      if let Ok((id, user)) = res {\n          println!(\"{} - {:?}\", user);\n      }\n  }\n\n  // Update the user\n  let mut filter = User::filter();\n  filter.name = Some(Comparator::Eq(\"foo\".to_owned()));\n  let mut update = User::update();\n  update.age = Some(Some(0));\n  let updates = Updates {\n      set: Some(update),\n      ..Default::default()\n  };\n  let updated = client.update::\u003cUser, _, _\u003e(filter, updates).unwrap();\n  println!(\"updated {} documents\", updated);\n\n  // Delete all users\n  let deleted = client.delete::\u003cUser, _\u003e(None).unwrap();\n  println!(\"delete {} documents\", deleted);\n}\n```\n\n## Complex Queries\n\nSometimes the convenience queries provided on the client are not enough, the query builders can be used instead.\n\n```rust\nuse mongod::Query;\n\n...\n\nlet result = Query::insert::\u003cUser\u003e::new()\n    .document_validation(false)\n    .ordered(false)\n    .query(\u0026client, vec![user])\n    .await\n    .unwrap();\n\n...\n```\n\n## Serde\n\nSometimes there are reasons that implenting `TryFrom` is just too difficult, but serde implentations already exist.\nBy tweaking the `Mongo` derive it can be changed to be serde backed.\n\n```rust\nuse mongod::Mongo;\n\n#[derive(Debug, Mongo)]\n#[mongo(bson = \"serde\", collection = \"users\", field, filter, update)]\npub struct User {\n  pub name: String,\n  pub age: Option\u003cu32\u003e,\n}\n\n...\n```\n\n## Too Many Opinions\n\nThis library is too opinionated but I wanna use the derives...\nWell as the derives are basically just fancy ways to convert rust types into BSON, they can be used without the `mongod` clients.\nBelow is an example of the `mongodb` client but using a `mongod` derived user.\n\n```rust\nuse mongod::{Bson, Mongo};\nuse mongod::Collection;\nuse mongod::db::Client;\n\n#[derive(Debug, Bson, Mongo)]\n#[mongo(collection = \"users\", field, filter, update)]\npub struct User {\n  pub name: String,\n}\n\nlet client = Client::with_uri_str(\"mongodb://localhost:27017/\").await.unwrap();\nlet db = client.database(\"db\");\nlet users = db.collection(\"users\");\nlet user = User { name: \"foo\".to_owned() };\nlet result = users.insert_one(user.into_document().unwrap(), None).unwrap();\n```\n\n## TODO\n\n- Add proc macro tests\n- Not all features have been implented yet...\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithsecurelabs%2Fmongo-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwithsecurelabs%2Fmongo-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwithsecurelabs%2Fmongo-rs/lists"}