快速入门:将 Azure DocumentDB 与用于 Rust 的 MongoDB 驱动程序配合使用

在本快速入门中,你将使用 Rust 创建基本的 Azure DocumentDB 应用程序。 Azure DocumentDB 是一种NoSQL数据存储,允许应用程序将文档存储在云中,并使用官方 MongoDB 驱动程序访问文档。 本指南演示如何使用 Rust 在 Azure DocumentDB 群集中创建文档和执行基本任务。

API 参考 | 源代码 | 包 (crates.io)

先决条件

  • 一份 Azure 订阅。 如果没有 Azure 订阅,请创建一个试用帐户。
  • Rust 1.70 或更高版本

创建 Azure DocumentDB 群集

若要开始,首先需要创建一个 Azure DocumentDB 群集,该群集充当存储和管理NoSQL数据的基础。

  1. 登录到 Azure 门户(https://portal.azure.cn)。

  2. 在Azure门户菜单或 Home 页面中,选择创建资源。

  3. 在 New 页上,搜索并选择 Azure DocumentDB。

    截图显示对 Azure DocumentDB 的搜索。

  4. 在 Create Azure DocumentDB 群集页上,并在 Basics 节中, 在 Cluster 层节中选择 Configure 选项。

    显示“配置群集”选项的屏幕截图。

  5. 在“ 缩放 ”页上,配置这些选项,然后选择“ 保存 ”以将更改保存到群集层。

    价值
    群集层 M30 tier, 2 vCore, 8-GiB RAM
    每个分片的存储量 128 GiB

    新建 Azure DocumentDB 群集的计算和存储配置选项的屏幕截图

  6. 返回 “基本信息 ”部分,配置以下选项:

    价值
    Subscription 选择Azure订阅
    资源组 创建新的资源组,或选择现有资源组
    群集名称 提供一个全局唯一的名称
    位置 为订阅选择受支持的Azure区域
    MongoDB 版本 选择 8.0
    管理员用户名 创建用户名以以用户管理员身份访问群集
    密码 使用与用户名关联的唯一密码

    显示群集参数的屏幕截图。

    小窍门

    记录用于用户名和密码的值。 本指南稍后会使用这些值。 有关有效值的详细信息,请参阅 群集限制。

  7. 选择下一步:网络。

  8. 在“网络”选项卡上的“防火墙规则”部分中,配置以下选项:

    价值
    连接方法 Public access
    允许Azure中的服务和资源公开访问此群集 已启用
  9. 为当前客户端设备添加防火墙规则,通过选择 “+ 添加当前客户端 IP 地址”来授予对群集的访问权限。

    显示网络配置的屏幕截图。

    小窍门

    在许多企业环境中,由于 VPN 或其他企业网络的设置,开发人员计算机 IP 地址会隐藏。 在这些情况下,可以通过将 IP 地址范围添加 0.0.0.0 - 255.255.255.255 为防火墙规则来暂时允许访问所有 IP 地址。 将此防火墙规则暂时用作连接测试和开发的一部分。

  10. 选择“查看 + 创建”。

  11. 查看提供的设置,然后选择“创建”。 创建群集需要几分钟时间。 等待资源部署完成。

  12. 最后,选择转到资源导航到门户中的 Azure DocumentDB 群集。

显示 goto 资源选项的屏幕截图。

获取群集凭据

获取用于连接到群集的凭据。

  1. 在群集页上,在资源菜单中选择 “连接字符串 ”选项。

  2. 在 “连接字符串 ”部分中,复制或记录 “连接字符串 ”字段中的值。

显示连接字符串选项的屏幕截图。

重要

门户中的连接字符串不包含密码值。 必须将占位符替换为 <password> 在创建群集时输入的凭据,或以交互方式输入密码。

初始化项目

在当前目录中创建新的 Rust 项目。

  1. 从空目录中开始。

  2. 在当前目录中打开终端。

  3. 使用 Cargo 创建新的 Rust 项目。

    cargo new azure-documentdb-rust-quickstart
    cd azure-documentdb-rust-quickstart
    

安装客户端库

客户端库可通过 crates.io 以 mongodb crate 的形式提供。

  1. 使用 Cargo 添加 MongoDB Rust 驱动程序。

    cargo add mongodb
    
  2. 为异步操作添加 tokio 运行时。

    cargo add tokio --features full
    
  3. 添加serde crate以支持序列化。

    cargo add serde --features derive
    
  4. 添加用于异步流操作的futures库。

    cargo add futures
    
  5. 请打开应用程序代码文件src/main.rs。

  6. 将所需的模块导入应用程序代码:

    use futures::TryStreamExt;
    use mongodb::{
        bson::doc,
        options::ClientOptions,
        Client, Collection,
    };
    use serde::{Deserialize, Serialize};
    

对象模型

名称 说明
Client 用于连接到 MongoDB 的类型。
Database 表示群集中的数据库。
Collection<T> 表示群集中数据库内的集合。

代码示例

此应用程序中的代码连接到名为adventureworks的数据库和名为products的集合。 该 products 集合包含每个产品的名称、类别、数量、唯一标识符和销售标志等详细信息。 此处的代码示例在处理集合时执行最常见的作。

对客户端进行身份验证

首先,使用基本的连接字符串连接到客户端。

  1. 创建主异步函数并设置连接字符串。 替换 <your-cluster-name>、<your-username> 和 <your-password> 为实际群集信息。

    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        // Connection string for Azure DocumentDB cluster
        let connection_string = "mongodb+srv://<your-username>:<your-password>@<your-cluster-name>.global.mongocluster.cosmos.azure.cn/?tls=true&authMechanism=SCRAM-SHA-256&retrywrites=false&maxIdleTimeMS=120000";
    
        // Parse connection string into client options
        let client_options = ClientOptions::parse(connection_string).await?;
    
  2. 创建 MongoDB 客户端并验证连接。

        // Create a new client and connect to the server
        let client = Client::with_options(client_options)?;
    
        // Ping the server to verify connection
        client
            .database("admin")
            .run_command(doc! { "ping": 1 })
            .await?;
    
        println!("Successfully connected and pinged Azure DocumentDB");
    

获取集合

现在获取数据库和集合。 如果数据库和集合尚不存在,请使用驱动程序自动创建它。

  1. 获取对数据库的引用。

        // Get database reference
        let database = client.database("adventureworks");
        println!("Connected to database: {}", database.name());
    
  2. 获取对数据库中集合的引用。

        // Get collection reference
        let collection: Collection<Product> = database.collection("products");
        println!("Connected to collection: products");
    

创建文档

然后,在集合中创建几个新文档。 向上插入文档,以确保它已使用同一唯一标识符替换任何现有文档。

  1. 定义产品结构并创建示例产品文档。

        // Define Product struct for type-safe operations
        #[derive(Debug, Serialize, Deserialize)]
        struct Product {
            #[serde(rename = "_id")]
            id: String,
            name: String,
            category: String,
            quantity: i32,
            price: f64,
            sale: bool,
        }
    
        // Create sample products
        let products = vec![
            Product {
                id: "00000000-0000-0000-0000-000000004018".to_string(),
                name: "Windry Mittens".to_string(),
                category: "apparel-accessories-gloves-and-mittens".to_string(),
                quantity: 121,
                price: 35.00,
                sale: false,
            },
            Product {
                id: "00000000-0000-0000-0000-000000004318".to_string(),
                name: "Niborio Tent".to_string(),
                category: "gear-camp-tents".to_string(),
                quantity: 140,
                price: 420.00,
                sale: true,
            },
        ];
    
  2. 通过upsert操作插入文档。

        // Insert documents with upsert
        for product in &products {
            let filter = doc! { "_id": &product.id };
            let update = doc! { "$set": mongodb::bson::to_document(product)? };
    
            let result = collection
                .update_one(filter, update)
                .upsert(true)
                .await?;
    
            if result.upserted_id.is_some() {
                println!("Inserted document with ID: {}", product.id);
            } else {
                println!("Updated document with ID: {}", product.id);
            }
        }
    

检索文档

接下来,执行点读取操作,从集合中检索特定文档。

  1. 定义筛选器以按 ID 查找特定文档。

        // Retrieve a specific document by ID
        let filter = doc! { "_id": "00000000-0000-0000-0000-000000004018" };
    
  2. 执行查询并检索结果。

        let retrieved_product = collection.find_one(filter).await?;
    
        match retrieved_product {
            Some(product) => println!("Retrieved product: {} - ${:.2}", product.name, product.price),
            None => println!("Product not found"),
        }
    

查询文档

最后,使用 MongoDB 查询语言(MQL)查询多个文档。

  1. 定义查询以查找符合特定条件的文档。

        // Query for products on sale
        let query_filter = doc! { "sale": true };
        let mut cursor = collection.find(query_filter).await?;
    
  2. 遍历游标以检索所有匹配的文档。

        println!("Products on sale:");
        while let Some(product) = cursor.try_next().await? {
            println!(
                "- {}: ${:.2} (Category: {})",
                product.name, product.price, product.category
            );
        }
    
        Ok(())
    }
    

使用 Visual Studio Code 浏览数据

使用 适用于 Visual Studio Code 的 DocumentDB 扩展浏览数据并运行查询,而无需离开编辑器。 安装扩展,然后按照使用 Visual Studio Code 连接连接到群集。

对于公共连接,允许您的客户端 IP 地址访问。 对于专用连接,请使用可以访问群集专用终结点的开发环境。

  1. 在边栏中展开群集,然后打开包含本快速入门创建的 products 集合的数据库。

  2. 打开 products 的上下文菜单,然后选择“新建查询操场”。 演练场会自动连接到该群集和数据库。

  3. 将生成的示例替换为以下查询:

    db.products.find({
      price: { $gt: 200 },
      sale: true
    })
    .sort({ price: -1 })
    .limit(3)
    
  4. 选择块上方的“运行”。 结果显示在侧面板中。

  5. 将脚本保存为 .documentdb.js 文件,以便稍后再次运行。

清理资源

完成 Azure DocumentDB 群集后,可以删除创建的Azure资源,以免产生更多费用。

  1. 在Azure门户搜索栏中,搜索并选择资源组。

    显示用于搜索资源组的选项的屏幕截图。

  2. 在列表中选择为本快速入门使用的资源组。

    显示资源组的屏幕截图。

  3. 在资源组页上,选择“删除资源组”。

  4. 在删除确认对话框中,输入资源组的名称以确认要删除它。 最后,选择“删除”以永久删除资源组。

    显示“删除资源组确认”按钮的屏幕截图。