使用 Rust 開始使用 MongoDB

介紹

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 盒子。

以前的要求

在執行本指南中的步驟之前,您必須:

  1. 部署新的雲服務器Ubuntu22.04 LTS Vultr。

  2. 創建一個非 root sudo 用戶。

  3. 安裝泊塢窗。

  4. 安裝最新版本的 Rust.

創建一個新的 Rust 項目

  1. 以非 root 用戶身份通過 SSH 連接到您在先決條件部分中部署的 Ubuntu 服務器。

  2. 創建一個新的 Rust 項目並切換到目錄:

                              
                                $ cargo new mongodb-rust
    
    $ cd mongodb-rust
    
                              
                            

    這將創建一個新的 Cargo 包括一個包 Cargo.toml 宣言和一個 src/main.rs 程序。

  3. 替換內容 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

  1. 替換內容 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}
    
        }
    
    }
    
                              
                            
  2. 構建程序:

                              
                                $ cargo build
    
                              
                            

    編譯並構建程序後,您應該會看到類似如下的輸出:

                              
                                Finished dev [unoptimized + debuginfo] target(s) in 10.10s
    
                              
                            
  3. 運行程序:

                              
                                $ 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")

}

                      
                    

測試應用

  1. 重建程序:

                              
                                $ 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
    
                              
                            
  2. 切換到應用程序二進製文件所在的目錄:

                              
                                $ 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

文章標題 名稱(可選) 電子郵件(可選) 描述

發送建議

相關文章