12 个版本
0.3.5 | 2024年5月25日 |
---|---|
0.3.3 | 2022年10月17日 |
0.3.1 | 2022年2月14日 |
0.3.0 | 2021年8月10日 |
0.2.0 | 2021年2月15日 |
#205 在 数据库接口 中
150KB
3K SLoC
Mongo
在官方 bson & mongodb Crates 之上的高级包装器。
概述
mongod
Crates 是一个非官方的高级包装器,旨在使 bson & mongodb Crates 更符合 Rust 风格。
提供以下功能
- 构建器风格查询
- 支持异步/非异步的客户端
- 为
Bson
&Mongo
提供推导,以帮助进行 BSON 类型转换和实现此 Crates 提供的特质 - 通过特质的使用表达强烈的观点
示例
futures = "0.3"
mongod = { version = "0.3", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
use futures::stream::StreamExt;
use mongod::{Bson, Mongo};
use mongod::{AsFilter, AsUpdate, Collection, Comparator, Updates};
#[derive(Debug, Bson, Mongo)]
#[mongo(collection = "users", field, filter, update)]
pub struct User {
pub name: String,
pub age: Option<u32>,
}
#[tokio::main]
async fn main() {
// Create and async client
let client = mongod::Client::new();
// Insert a user into the users collection
let user = User { name: "foo".to_string(), age: None };
let oid = client.insert_one::<User>(user).await.unwrap();
println!("{:?}", oid);
// Fetch all users in the users collection
let mut cursor = client.find::<User, _>(None).await.unwrap();
while let Some(res) = cursor.next().await {
if let Ok((id, user)) = res {
println!("{} - {:?}", id, user);
}
}
// Update the user
let mut filter = User::filter();
filter.name = Some(Comparator::Eq("foo".to_owned()));
let mut update = User::update();
update.age = Some(Some(0));
let updates = Updates {
set: Some(update),
..Default::default()
};
let updated = client.update::<User, _, _>(filter, updates).await.unwrap();
println!("updated {} documents", updated);
// Delete all users
let deleted = client.delete::<User, _>(None).await.unwrap();
println!("delete {} documents", deleted);
}
客户端
异步
默认客户端是异步的,并提供了比 mongodb 驱动程序暴露的更多便利函数。
示例:见上文。
阻塞
并非所有内容都应该是异步的,因此提供了一个阻塞客户端,可以与异步客户端同时使用。
mongod = { version = "0.3", features = ["blocking", "derive"] }
use mongod::{Bson, Mongo};
use mongod::{AsFilter, AsUpdate, Collection, Comparator, Updates};
#[derive(Debug, Bson, Mongo)]
#[mongo(collection = "users", field, filter, update)]
pub struct User {
pub name: String,
pub age: Option<u32>,
}
fn main() {
// Create and async client
let client = mongo::blocking::Client::new();
// Insert a user into the users collection
let user = User { name: "foo".to_string(), age: None };
let oid = client.insert_one::<User>(user).unwrap();
println!("{:?}", oid);
// Fetch all users in the users collection
let mut cursor = client.find::<User, _>(None).unwrap();
while let Some(res) = cursor.next() {
if let Ok((id, user)) = res {
println!("{} - {:?}", user);
}
}
// Update the user
let mut filter = User::filter();
filter.name = Some(Comparator::Eq("foo".to_owned()));
let mut update = User::update();
update.age = Some(Some(0));
let updates = Updates {
set: Some(update),
..Default::default()
};
let updated = client.update::<User, _, _>(filter, updates).unwrap();
println!("updated {} documents", updated);
// Delete all users
let deleted = client.delete::<User, _>(None).unwrap();
println!("delete {} documents", deleted);
}
复杂查询
有时客户端提供的便利查询不足以满足需求,可以使用查询构建器代替。
use mongod::Query;
...
let result = Query::insert::<User>::new()
.document_validation(false)
.ordered(false)
.query(&client, vec![user])
.await
.unwrap();
...
序列化/反序列化
有时实现 TryFrom
太困难,但已经存在 serde 实现的情况。通过调整 Mongo
推导,可以将其改为基于 serde。
use mongod::Mongo;
#[derive(Debug, Mongo)]
#[mongo(bson = "serde", collection = "users", field, filter, update)]
pub struct User {
pub name: String,
pub age: Option<u32>,
}
...
过多的观点
这个库太有观点了,但我想使用推导... 好吧,因为推导基本上只是将 Rust 类型转换为 BSON 的花哨方式,所以可以在不使用 mongod
客户端的情况下使用它们。以下是一个使用 mongodb
客户端的示例,但使用了 mongod
推导的用户。
use mongod::{Bson, Mongo};
use mongod::Collection;
use mongod::db::Client;
#[derive(Debug, Bson, Mongo)]
#[mongo(collection = "users", field, filter, update)]
pub struct User {
pub name: String,
}
let client = Client::with_uri_str("mongodb://127.0.0.1:27017/").await.unwrap();
let db = client.database("db");
let users = db.collection("users");
let user = User { name: "foo".to_owned() };
let result = users.insert_one(user.into_document().unwrap(), None).unwrap();
待办事项
- 添加 proc macro 测试
- 并非所有功能都已实现...
依赖关系
~24–36MB
~663K SLoC