Expand description
Khan is a MongoDB ORM (or, more precisely, an ODM) for Rust. It adds an entity API on top of the
underlying MongoDB driver, with type-safe methods to create, query, update, and delete documents,
as well as tools for maintaining consistency in multi-document transactions.
It can also manage collection indexes and validation rules in a code-first manner.
§Why Khan?
Khan is designed for applications that want Rust’s type system around everyday MongoDB work
without hiding MongoDB itself.
- 🛡️ Typed where repetition is costly. Deriving
Entitygenerates typed filters, updates, field names, projections, and CRUD methods from the same Serde model used for BSON. - 🧰 Explicit where
MongoDBis powerful. Raw BSON filters and updates remain deliberate escape hatches, while the underlyingmongodbAPI stays available for aggregation pipelines and specialized operations. - 🔄 Transaction-aware by construction. Entity operations work with either a database or a
transaction context.
DatabaseExtprovides retry-aware transaction helpers, whileFencecan express document-level reference requirements in function signatures. - 🧩 Code-first database metadata. Optional features let entity declarations define and enforce
indexes, query-expression validators, and
MongoDBJSON Schema validation. - 🎯 A focused, composable API. Khan handles common persistence and consistency concerns while
application architecture, domain behavior, and advanced
MongoDBoperations remain ordinary Rust code.
§Example
// Define an entity
#[derive(Serialize, Deserialize, Entity, Debug, PartialEq, Eq)]
#[entity(
skip_schema_validation,
collection = "readme_user",
// Define supported projections; respective structs are generated automatically.
projections(Profile(id, email, password))
)]
struct User {
#[serde(rename = "_id")]
id: ObjectId,
email: String,
username: String,
password: String,
}
// Insert an entity into the database
let user = User {
id: ObjectId::new(),
email: "mail@example.com".into(),
username: "nikis05".into(),
password: "somepassword".into(),
};
let user_id = user.id;
user.insert(mongo).await?;
assert_eq!(User::find_one(mongo, by_id(user_id)).await?, Some(user));
// Query an entity by id
let person: User = User::find_one(mongo, by_id(user_id)).await?.unwrap();
assert_eq!(person.email, "mail@example.com");
// Query an entity by custom fields
let recent_user: User = User::find_one(mongo, user::filter! {
username: "nikis05"
}).await?.unwrap();
assert_eq!(recent_user.id, user_id);
// Query only the necessary fields of an entity
// into a custom projection struct
let user::Profile { email, password, .. } = user::Profile::find_one(mongo, by_id(user_id)).await?.unwrap();
assert_eq!(email, "mail@example.com");
assert_eq!(password, "somepassword");
// Update an entity in the database
User::update_one(mongo, by_id(user_id), user::update! {
email: "new.email@example.com".into()
}).await?;
assert_eq!(User::find_one(mongo, by_id(user_id)).await?.unwrap().email, "new.email@example.com");
// Update an entity in the database and the corresponding struct
let mut user = User::find_one(mongo, by_id(user_id)).await?.unwrap();
user.patch(mongo, user::update! {
email: "newer.email@example.com".into(),
password: "someotherpassword".into()
}).await?;
assert_eq!(User::find_one(mongo, by_id(user_id)).await?.unwrap().password, "someotherpassword");
assert_eq!(user.password, "someotherpassword");
// Delete one entity matching the filter
let result = User::delete_one(mongo, by_id(user_id)).await?;
assert!(result.deleted());
assert!(User::find_one(mongo, by_id(user_id)).await?.is_none());
// Remove a document from the database that corresponds to an instance
let removable = User {
id: ObjectId::new(),
email: "remove@example.com".into(),
username: "remove-me".into(),
password: "temporary".into(),
};
let removable_id = removable.id;
removable.insert(mongo).await?;
removable.remove(mongo).await?;
assert!(User::find_one(mongo, by_id(removable_id)).await?.is_none());See guides module to learn more!
§Crate features
meta- enables Khan to manage collection indexes and expression-based validation rules.schema- enables generation ofMongoDBJSON Schema validation rules. Participating entities must deriveJsonSchemaand use BSON-compatible types. Individual entities can opt out with#[entity(skip_schema_validation)]. Apply generated rules withmeta::enforce_validation.guides- internal feature for documentation purposes.
Re-exports§
Modules§
- guides
- High-level usage guides for Khan, covering core concepts like CRUD, filters, projections, transactions, and design patterns. Start here.
- meta
- Tools for managing indexes and validation rules on collections.
- prelude
- Convenient imports for Khan’s common entity and database operations.
- types
- BSON-compatible types for use with JSON Schema validation.
Structs§
- Delete
Result - A wrapper around
mongodb::results::DeleteResult, representing the outcome of a delete operation. - Fence
- A type-level marker indicating that a document has been fenced in the current transaction.
- Filter
ById - A simple filter that matches a document by its
idfield. - Find
Options - Options for
Selectable::find_with_opts. - Index
Map - A hash table where the iteration order of the key-value pairs is independent of the hash values of the keys.
- Untyped
Filter - A raw BSON filter for an entity, bypassing Khan’s typed filter system.
- Untyped
Update - A raw BSON update for an entity, bypassing Khan’s typed update system.
- Untyped
Update Apply - A raw BSON update paired with an in-memory update function.
- Update
Result - A wrapper around
mongodb::results::UpdateResultthat represents the result of an update operation on aMongoDBcollection.
Enums§
- Field
- A wrapper used in Khan’s typed filters and updates to mark field usage.
- Filter
Operator - Represents a typed
MongoDBcomparison operator for a specific field. - Order
- Sort direction for
MongoDBqueries and index definitions.
Traits§
- Database
Ext - Convenience methods for running transactions.
- Entity
- Core trait representing a
MongoDBdocument. - Filter
- Trait representing a
MongoDBquery filter for a given entity type. - Json
Schema - A type which can be described as a JSON Schema document.
- Mongo
- A
MongoDBdatabase, optionally paired with a transaction session. - Selectable
- Trait that represents either a complete entity or a partial projection of it.
- Selectable
With Id - Extension of
Selectablefor projections that include theidfield. - Transaction
- A
MongoDBdatabase context with an active transaction session. - Update
- Trait representing an update expression for a given entity type.
- Update
Apply - Trait for applying an update to an in-memory projection.
Functions§
- by_id
- Creates a filter that matches a document by its
id.
Derive Macros§
- Entity
- Derives Khan’s
Entitytrait for a struct and generates its typed CRUD helpers. - Fields
- Generates a field-name enum for a struct without deriving
Entity. - Json
Schema