You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust连接MongoDB出现类型不匹配错误,求解决方案

Rust连接MongoDB编译错误:类型不匹配问题

编写的Rust连接MongoDB代码在执行cargo run时,if语句处触发编译错误,错误提示为Expected Result<Option<Value>, Error>, found Result<Option<&...>, ...>,需要修复该问题以让database_connection()函数能被Rocket路由调用。

原代码

use std::iter::FilterMap;
use rocket::serde::json::{json, Value};
use futures::{StreamExt};
use mongodb::{bson::doc, options::ClientOptions, Client};
use bson::{Document};
use warp::body::json;

/**
 * MongoDB client
 */
#[tokio::main]
pub async fn database_connection(key: &str, value: &str) -> Result<Option<Value>, mongodb::error::Error> {

    // uri to connect to the database
    let uri = "mongodb://admin:adminpassword@localhost:27017";
    
    // options to connect to the database
    let mut client_options =
        ClientOptions::parse(uri)
        .await?;

    // Create a new client and connect to the server with the given options
    let client = Client::with_options(client_options)?;

    //Connect to the BinGo! database
    let material = client.database("BinGo!");
    
    // Search thrue a collection
    let collection = material.collection::<Document>("bingo_materials");
    
    let filter = doc! {
        key: value
    };
    
    print!("Making the query to the database...\n");
    
    println!("Filter: {:#?}", filter);
    print!("-------------------------\n");

    let mut cursor = collection.
                find(filter, None)
                .await?;
    
    if let  Some(result) = cursor.next().await {
        println!("{:#?}", result);
        let result_json: &Result<Document, mongodb::error::Error> = &result;
        return Ok(Some(result_json));
    } else {
        return Ok(None);
    }
}

错误详情

error[E0308]: mismatched types
  --> src/databases.rs:57:5
   |
25 |   pub async fn database_connection(key: &str, value: &str) -> Result<Option<Value>, mongodb::error::Error> {
   |                                                               -------------------------------------------- expected `Result<std::option::Option<rocket_dyn_templates::tera::Value>, mongodb::error::Error>` because of return type
...
57 | /     if let  Some(result) = cursor.next().await {
58 | |         println!("{:#?}", result);
59 | |         let result_json: &Result<Document, mongodb::error::Error> = &result;
60 | |         return Ok(Some(result_json));
61 | |     }else{
62 | |         return Ok(None);
63 | |     }
   | |_____^ expected `Result<Option<Value>, Error>`, found `Result<Option<&...>, ...>`
   |
   = note: expected enum `Result<std::option::Option<rocket_dyn_templates::tera::Value>, mongodb::error::Error>`
              found enum `Result<std::option::Option<&Result<bson::Document, mongodb::error::Error>>, _>`

解决方法

错误原因分析

  1. 类型不匹配:函数声明返回Result<Option<rocket::serde::json::Value>, mongodb::error::Error>,但代码中返回的是&Result<Document, mongodb::error::Error>,两者类型完全不兼容。
  2. 错误处理缺失:cursor.next().await返回的Some(result)中的result本身是Result<Document, mongodb::error::Error>,需要先处理这个层级的错误,而不是直接取引用。
  3. 类型转换缺失:需要将MongoDB的bson::Document转换为Rocket的json::Value类型。

修复步骤

  1. 处理cursor.next().await返回的Result错误:使用?操作符提取Document。
  2. 将Document转换为rocket::serde::json::Value:利用bson::to_value方法完成转换(需确保bson依赖启用serde特性)。
  3. 移除不必要的引用,直接返回符合函数声明的类型。
  4. 移除#[tokio::main]宏:Rocket自身会管理异步运行时,无需单独标注。

修正后的代码

use rocket::serde::json::Value;
use futures::StreamExt;
use mongodb::{bson::doc, options::ClientOptions, Client};
use bson::{Document, to_value};

/**
 * MongoDB client
 */
pub async fn database_connection(key: &str, value: &str) -> Result<Option<Value>, mongodb::error::Error> {
    // 数据库连接URI
    let uri = "mongodb://admin:adminpassword@localhost:27017";
    
    // 解析客户端连接选项
    let client_options = ClientOptions::parse(uri).await?;

    // 创建客户端并连接
    let client = Client::with_options(client_options)?;

    // 连接到BinGo!数据库
    let db = client.database("BinGo!");
    
    // 获取bingo_materials集合
    let collection = db.collection::<Document>("bingo_materials");
    
    // 构建查询过滤器
    let filter = doc! { key: value };
    
    println!("Making the query to the database...");
    println!("Filter: {:#?}", filter);
    println!("---------------------------------");

    // 执行查询获取游标
    let mut cursor = collection.find(filter, None).await?;
    
    // 处理游标结果
    if let Some(doc_result) = cursor.next().await {
        // 处理单条文档的查询错误
        let doc = doc_result?;
        // 将Document转换为Rocket的JSON Value
        let json_value = to_value(&doc)?;
        Ok(Some(json_value))
    } else {
        // 无匹配文档
        Ok(None)
    }
}

依赖配置说明

确保Cargo.toml中的bson依赖启用serde特性,同时配置好Rocket等依赖:

[dependencies]
bson = { version = "2.0", features = ["serde"] }
rocket = { version = "0.5", features = ["json"] }
mongodb = "2.0"
futures = "0.3"
tokio = { version = "1.0", features = ["full"] }

内容的提问来源于stack exchange,提问作者Elia Todescato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:02:06