介紹
MongoDB
是一個 NoSQL 數據庫,它將數據存儲在由字段值對組成的文檔中。 這些存儲使用 BSON
的二進製表示 JSON
文件。 MongoDB 文檔相當於關係數據庫表中的行,文檔字段(鍵值對)類似於列。 MongoDB 文檔是 collection
並且一個或多個集合是 database
. MongoDB 有一個支持常規的 API CRUD
操作(創建、讀取、更新、刪除)以及聚合、地理空間查詢和文本搜索。 MongoDB 還提供高可用性和復制。 可以跨多個 MongoDB 服務器(稱為副本集)分佈數據以提供冗餘和分片。
MongoDB 有幾個官方支持的客戶端驅動程序。 其中包括 Java、Python、Node.js、PHP、Ruby、Swift、C、C++、C#、Go 和 Rust。
在本文中,您將通過構建一個簡單的命令行應用程序來了解如何使用適用於 MongoDB 的 Rust 驅動程序。
MongoDB Rust 驅動程序
MongoDB Rust 驅動程序用於從 Rust 應用程序與 MongoDB 交互。 儘管本文中的應用程序使用同步 API,但 Rust 驅動程序還提供異步 API。
它支持異步運行時框: tokio
和 async-std
. tokio
是默認運行時,但您可以通過使用中的功能標誌選擇運行時來覆蓋它 Cargo.toml
.
除了異步 API 之外,MongoDB Rust 驅動程序支持的一些重要功能標誌包括:
-
openssl-tls
: TLS 連接處理由openssl
. -
bson-uuid-1
- 支持v1.x
的uuid
在重新導出的公共 API 中打包bson
盒子。 -
bson-serde_with
: 我支持serde_with
在重新導出的公共 API 中打包bson
盒子。
以前的要求
在執行本指南中的步驟之前,您必須:
-
部署新的雲服務器Ubuntu22.04 LTS Vultr。
-
創建一個非 root sudo 用戶。
-
安裝泊塢窗。
創建一個新的 Rust 項目
-
以非 root 用戶身份通過 SSH 連接到您在先決條件部分中部署的 Ubuntu 服務器。
-
創建一個新的 Rust 項目並切換到目錄:
$ cargo new mongodb-rust $ cd mongodb-rust
這將創建一個新的
Cargo
包括一個包Cargo.toml
宣言和一個src/main.rs
程序。 -
替換內容
Cargo.toml
文件如下:[package] name = "user-app" version = "0.1.0" edition = "2018" [dependencies.mongodb] version = "1.1.1" default-features = false features = ["sync"] [dependencies.serde] version = "1.0.118" [dependencies.bson] version = "1.1.0"
啟動 MongoDB 容器
在 Ubuntu 服務器上,使用 Docker 啟動 MongoDB 容器。
$ docker run -it --rm -p 27017:27017 mongo
容器啟動後,就可以通過端口訪問 MongoDB 27017
.
使用 Rust 驅動程序連接到 MongoDB
-
替換內容
src/main.rs
包含以下代碼的文件:use mongodb::sync::Client; use mongodb::sync::Collection; use mongodb::bson::{doc, Bson}; use serde::{Deserialize, Serialize}; struct UsersManager { coll: Collection } fn main() { let conn_string = std::env::var_os("MONGODB_URL").expect("missing environment variable MONGODB_URL").to_str().expect("missing MONGODB_URL").to_owned(); let users_db = std::env::var_os("MONGODB_DATABASE").expect("missing environment variable MONGODB_DATABASE").to_str().expect("missing MONGODB_DATABASE").to_owned(); let users_collection = std::env::var_os("MONGODB_COLLECTION").expect("missing environment variable MONGODB_COLLECTION").to_str().expect("missing MONGODB_COLLECTION").to_owned(); let um = UsersManager::new(conn_string,users_db.as_str(), users_collection.as_str()); } impl UsersManager{ fn new(conn_string: String, db_name: &str, coll_name: &str) -> Self{ let mongo_client = Client::with_uri_str(&*conn_string).expect("failed to create client"); println!("successfully connected to mongodb"); let users_coll = mongo_client.database(db_name).collection(coll_name); UsersManager{coll: users_coll} } }
-
構建程序:
$ cargo build
編譯並構建程序後,您應該會看到類似如下的輸出:
Finished dev [unoptimized + debuginfo] target(s) in 10.10s
-
運行程序:
$ export MONGODB_URL=mongodb://localhost:27017 $ export MONGODB_DATABASE=users-db $ export MONGODB_COLLECTION=users $ cargo run
如果已連接,您應該會看到以下輸出:
successfully connected to mongodb
添加 User
結構
將下面的代碼添加到 src/main.rs
程序:
#[derive(Serialize, Deserialize)]
struct User {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
user_id: Option<bson::oid::ObjectId>,
#[serde(rename = "description")]
email: String,
status: String,
}
添加創建用戶的方法
將下面的代碼添加到 src/main.rs
文件(在 impl UsersManager
之後 new
方法):
fn add_user(self, email: &str) {
let new_user = User {
user_id: None,
email: String::from(email),
status: String::from("enabled"),
};
let user_doc = mongodb::bson::to_bson(&new_user).expect("conversion failed").as_document().expect("conversion failed").to_owned();
let insert_result = self.coll.insert_one(user_doc, None).expect("failed to add user");
println!("inserted user with id = {}", insert_result.inserted_id);
}
添加一個方法來列出所有用戶
將下面的代碼添加到 src/main.rs
文件(在 impl UsersManager
之後 add_user
方法):
fn list_users(self, status_filter: &str) {
let mut filter = doc!{};
if status_filter == "enabled" || status_filter == "disabled"{
println!("listing '{}' users",status_filter);
filter = doc!{"status": status_filter}
} else if status_filter != "all" {
panic!("invalid user status")
}
let mut users = self.coll.find(filter, None).expect("failed to find users");
while let Some(result) = users.next() {
let user_doc = result.expect("user not present");
let user: User = bson::from_bson(Bson::Document(user_doc)).expect("conversion failed");
println!("user_id: {} nemail: {} nstatus: {}n=========", user.user_id.expect("user id missing"), user.email, user.status);
}
}
添加更新用戶狀態的方法
將下面的代碼添加到 src/main.rs
文件(在 impl UsersManager
之後 list_users
方法):
fn update_user(self, user_id: &str, status: &str) {
if status != "enabled" && status != "disabled" {
panic!("invalid user status")
}
println!("updating user {} status to {}", user_id, status);
let id_filter = doc! {"_id": bson::oid::ObjectId::with_string(user_id).expect("user_id is not valid ObjectID")};
let r = self.coll.update_one(id_filter, doc! {"$set": { "status": status }}, None).expect("user update failed");
if r.modified_count == 1 {
println!("updated status for user id {}",user_id);
} else if r.matched_count == 0 {
println!("could not update. check user id {}",user_id);
}
}
添加刪除用戶的方法
將下面的代碼添加到 src/main.rs
文件(在 impl UsersManager
之後 update_user
方法):
fn delete_user(self, user_id: &str) {
let id_filter = doc! {"_id": bson::oid::ObjectId::with_string(user_id).expect("user_id is not valid ObjectID")};
self.coll.delete_one(id_filter, None).expect("delete failed").deleted_count;
println!("deleted user {}", user_id);
}
添加命令行操作
將以下代碼添加到 main
作用於 src/main.rs
程序:
let ops: Vec<String> = std::env::args().collect();
let operation = ops[1].as_str();
match operation {
"create" => um.add_user(ops[2].as_str()),
"list" => um.list_users(ops[2].as_str()),
"update" => um.update_user(ops[2].as_str(), ops[3].as_str()),
"delete" => um.delete_user(ops[2].as_str()),
_ => panic!("invalid user operation specified")
}
測試應用
-
重建程序:
$ cargo build --release
您應該看到類似於此的輸出(為簡潔起見,輸出已被編輯):
..... Compiling bson v1.2.4 Compiling mongodb v1.2.5 Compiling user-app v0.1.0 (/Users/demo/mongodb-rust) Finished release [optimized] target(s) in 37.84s
-
切換到應用程序二進製文件所在的目錄:
$ cd target/release
現在你可以試試 CRUD
命令行應用程序支持的(創建、讀取、更新、刪除)操作。
創建用戶
$ ./user-app create "[email protected]"
$ ./user-app create "[email protected]"
$ ./user-app create "[email protected]"
如果成功,對於創建的每個用戶,您應該看到 MongoDB 的輸出 _id
新創建的用戶:
inserted user with id = ObjectId("63b5648cbd0aa2dad409a3d7")
請注意,對象 ID 在您的情況下可能會有所不同。
列出所有用戶
$ ./user-app list all
您應該會看到在上一步中添加的用戶。
user_id: 63b5648cbd0aa2dad409a3d7
email: [email protected]
status: enabled
=========
user_id: 63b564c5f921fd0a9d0ea7ff
email: [email protected]
status: enabled
=========
user_id: 63b564c67f335133190fd1e2
email: [email protected]
status: enabled
=========
請注意,您的用戶(對象)ID 可能不同。
更新用戶狀態
指定要更新其狀態的用戶的用戶 ID,以及狀態 ( enabled
任何一個 disabled
):
$ ./user-app update 63b5648cbd0aa2dad409a3d7 disabled
請注意,您的用戶 ID(對象)可能有所不同。 使用數據庫中的那個。
你應該看到類似這樣的輸出:
updating user 63b5648cbd0aa2dad409a3d7 status to disabled
updated status for user id 63b5648cbd0aa2dad409a3d7
根據狀態的用戶列表
帶來 enabled
用戶:
$ ./user-app list enabled
你應該看到類似這樣的輸出:
listing 'enabled' users
user_id: 63b564c5f921fd0a9d0ea7ff
email: [email protected]
status: enabled
=========
user_id: 63b564c67f335133190fd1e2
email: [email protected]
status: enabled
=========
請注意,您的用戶(對象)ID 可能不同。
帶來 disabled
用戶:
$ ./user-app list disabled
你應該看到類似這樣的輸出:
listing 'disabled' users
user_id: 63b5648cbd0aa2dad409a3d7
email: [email protected]
status: disabled
=========
請注意,您的用戶 ID(對象)可能有所不同。
刪除用戶
指定要刪除的用戶的用戶 ID。
$ ./user-app delete 63b5648cbd0aa2dad409a3d7
請注意,您的用戶 ID(對象)可能有所不同。 使用數據庫中的那個。
你應該看到類似這樣的輸出:
deleted user 63b5648cbd0aa2dad409a3d7
請注意,您的用戶 ID(對象)可能有所不同。
列出所有用戶以確認
$ ./user-app list all
您應該會看到類似於此的輸出。 您之前刪除的用戶將不存在。
user_id: 63b564c5f921fd0a9d0ea7ff
email: [email protected]
status: enabled
=========
user_id: 63b564c67f335133190fd1e2
email: [email protected]
status: enabled
=========
請注意,您的用戶 ID(對象)可能有所不同。
結論
在本文中,您使用 Docker 啟動了一個 MongoDB 實例,並使用用 Rust 編寫的命令行應用程序與其進行交互。
您還可以在以下文檔中獲取更多信息:
-
在 Ubuntu 20.04 上安裝和配置 MongoDB 數據庫服務器
-
將 MongoDB 與 Node.JS 結合使用
-
如何在 Vultr Kubernetes Engine (VKE) 上安裝 MongoDB
-
保護 MongoDB
文章標題 名稱(可選) 電子郵件(可選) 描述
發送建議