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日

21#mongo

29 每月下载量
用于 mongod

MIT 许可证

59KB
1.5K SLoC

Mongo

crates.io Documentation

在官方 bson & mongodb 包的基础上提供更高层次的封装。

概述

mongod 包是一个非官方的高级封装,旨在使 bson & mongodb 包更加符合 Rust 风格。

提供以下功能

  • 构建器风格查询
  • 支持异步和非异步的客户端
  • Bson & Mongo 提供派生功能,以帮助进行 BSON 类型转换和实现该包提供的特性
  • 通过特性使用来表明强烈的观点

示例

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();

...

Serde

有时实现 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();

待办事项

  • 添加过程宏测试
  • 并非所有功能都已实现...

依赖项

~0.4–0.9MB
~20K SLoC