# Rust Mongodb 指南 **Repository Path**: star-dream-f/rust-mongodb---guide ## Basic Information - **Project Name**: Rust Mongodb 指南 - **Description**: 使用 Rust 进行项目开发。操作 MongoDB。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-05-16 - **Last Updated**: 2024-05-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 这里简单介绍 Rust 语言如何连接 MongoDB 数据库。 版本介绍 - Mongodb 6.0.7 - Rust rustc 1.76.0 (07dca489a 2024-02-04) - Cargo cargo 1.76.0 (c84b36747 2024-01-18) ## 搭建环境 如果熟悉 Rust 搭建项目,可以跳过本节内容。 ### 初始化项目 为了方便演示,这里创建一个新的文件夹。 ```sh mkdir mongodb cd mongodb ``` 创建我们的 Rust 项目,它和我们创建前端项目的步骤类似。 ```sh cargo init # 与 npm init 类似 D:. │ .gitignore │ Cargo.toml # 相当于 package.json 文件 │ └─src main.rs # 默认的二进制包根 ``` ### 添加依赖 依赖可以在官网查看:[https://crates.io/](https://crates.io/) 这里可以通过下面命令添加 Rust 的依赖: ```sh cargo add [模块名] ``` 移除模块 如果想要移除某个模块,可以手动在 `Cargo.toml` 文件中移除,也可以使用下面的命令: ```sh cargo remove [模块名] ``` 这里简单以 `time-rs` 依赖为例。 ```sh cargo add time ``` 查看配置文件,`[dependencies]`已成功添加: ```toml [package] name = "mongodb" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] time = "0.3.36" ``` 在添加依赖后,会生成 `Cargo.lock` 文件,目的是锁定版本,避免版本问题。 使用模块,可以参考下面代码: ```rs // src/main.rs use time::OffsetDateTime; fn main() { let now = OffsetDateTime::now_utc(); // let local = OffsetDateTime::now_local(); println!("{now}"); } ``` 编译运行,在项目根目录使用 `cargo run` 命令: ```sh Compiling mongodb v0.1.0 (D:\学习\Rust\mongodb) Finished dev [unoptimized + debuginfo] target(s) in 2.08s Running `target\debug\mongodb.exe` 2024-05-09 2:13:59.2477091 +00:00:00 ``` 在运行 Rust 项目时,会生成 `target` 目录。(一些文件夹或文件已省略) ```sh D:. └─target └─debug ├─.fingerprint │ ├─deranged-18559f2d1aa2f84b │ ├─mongodb-2bd418fca4f787a7 │ ├─num-conv-f19cfc73cc0280c4 │ ├─powerfmt-82d0abc0664de4d6 │ ├─time-6754357776d6406e │ └─time-core-fad5d4195fb29906 ├─build ├─deps ├─examples └─incremental ``` ### 连接 Mongodb 有了 `添加依赖` 的知识了解后,我们可以准备连接数据库了。由于 Mongodb 操作简单,这里以 `Mongodb` 数据库为例,其他数据库详细操作可以上网查询。 添加依赖,在 `Cargo.toml` 文件中添加,以及 `cargo build`: ```toml [dependencies] mongodb = "2.8.2" # 操作 Mongodb 数据库是异步的,需要依赖支持 tokio = { version = "1", features = ["full"] } # 查询文档时需要用到序列化、反序列化 serde = { version = "1.0.201", features = ["derive"] } serde_json = "1.0.117" ``` 参考文章 想要了解如何连接数据库,首先要熟悉下面的文章: - [推荐-官方 ※ MongoDB Rust 驱动程序快速入门](https://www.mongodb.com/zh-cn/docs/drivers/rust/current/quick-start/) - [如何在 Rust 中开始使用MongoDB - 知乎](https://zhuanlan.zhihu.com/p/692665114)。 - [Rust序列化、反序列化方案:Serde](https://blog.wangjunfeng.com/post/2024/rust-serde/) 1. 定义数据类型 要将数据保存在数据库中,我们要确定好数据的大致结构,在这里采用 `struct` 定义: ```rs #[derive(Debug, Serialize, Deserialize)] struct User { name: String, age: i32, } ``` 2. 创建好数据库 通过 `MongoDB Compass` 可视化软件去添加一个数据库。数据库名:`fly-test`,集合名:`rust`。 ![pkVHPhV.png](https://s21.ax1x.com/2024/05/09/pkVHPhV.png) 3. 准备连接 导入依赖: ```rs use mongodb::bson::doc; use mongodb::Collection; use mongodb::{options::ClientOptions, Client}; use serde::{Deserialize, Serialize}; ``` 创建好数据库和集合的实例: ```rs let db = client.database(db_name); // 填入你的数据库名 let coll: mongodb::Collection<_> = db.collection(coll_name); // 填入你的集合名 ``` 插入一条文档: ```rs let doc = doc! { "name": "John", "age": 30 }; coll.insert_one(doc, None).await.unwrap(); ``` 查询一条文档:这里以查询姓名为 John 为例。 ```rs // 创建的集合实例需要更改一下,将 User 类型添加进去 let coll: Collection<_> = db.collection::(coll_name); let filter = doc! { "name": "John"}; let result = coll.find_one(Some(filter), None).await.unwrap(); // 打印检索到的文档 match result { Some(doc) => println!("{:?}", doc), None => println!("No documents found"), } ``` 4. 大功告成 通过 `准备连接` 完成后,在终端输入 `cargo run` 命令,即可在控制台看到查询到的结果: ```sh PS D:\学习\Rust\mongodb> cargo run Compiling mongodb v0.1.0 (D:\学习\Rust\mongodb) Finished dev [unoptimized + debuginfo] target(s) in 3.96s Running `target\debug\mongodb.exe` User { name: "John", age: 30 } Runtime terminated. ``` 5. 完整代码 这里只展示 `src/main.rc` 文件中代码,其他文件默认。 ```rs use mongodb::bson::doc; use mongodb::Collection; use mongodb::{options::ClientOptions, Client}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] struct User { name: String, age: i32, } /** * MongoDB 数据库中创建一个新的集合 * * @param {Client} client - 连接到MongoDB数据库的客户端 * @param {string} db_name - 数据库的名称 * @param {string} coll_name - 集合的名称 */ #[allow(dead_code)] async fn create_collection(client: &Client, db_name: &str, coll_name: &str) { let db = client.database(db_name); db.create_collection(coll_name, None).await.unwrap(); } /** * MongoDB 数据库中插入一个新的文档 * @param {Client} client - 连接到MongoDB数据库的客户端 * @param {string} db_name - 数据库的名称 * @param {string} coll_name - 集合的名称 */ #[allow(dead_code)] async fn insert_document(client: &Client, db_name: &str, coll_name: &str) { let db = client.database(db_name); let coll: mongodb::Collection<_> = db.collection(coll_name); let doc = doc! { "name": "John", "age": 30 }; coll.insert_one(doc, None).await.unwrap(); } /** * MongoDb 数据库中检索文档 * * @param {Client} client - 连接到MongoDB数据库的客户端 * @param {string} db_name - 数据库的名称 * @param {string} coll_name - 集合的名称 */ async fn get_document(client: &Client, db_name: &str, coll_name: &str) { let db = client.database(db_name); let coll: Collection<_> = db.collection::(coll_name); let filter = doc! { "name": "John"}; let result = coll.find_one(Some(filter), None).await.unwrap(); // 打印检索到的文档 match result { Some(doc) => println!("{:?}", doc), None => println!("No documents found"), } } /** * 测试:向 MongoDB 数据库中插入一个新的文档 */ #[allow(dead_code)] async fn test_insert() { let client_options = ClientOptions::parse("mongodb://localhost:27017") .await .unwrap(); let client = Client::with_options(client_options).unwrap(); let db_name = "fly-test"; let coll_name = "rust"; insert_document(&client, db_name, coll_name).await; } /** * 测试:从 MongoDb 数据库读取一个文档 */ async fn test_read() { let client_options = ClientOptions::parse("mongodb://localhost:27017") .await .unwrap(); let client = Client::with_options(client_options).unwrap(); let db_name = "fly-test"; let coll_name = "rust"; get_document(&client, db_name, coll_name).await; } #[tokio::main] async fn main() { test_read().await; println!("Runtime terminated."); } ```