rust 如何从文档中获取字段值?

5lhxktic  于 2023-03-08  发布在  其他
关注(0)|答案(1)|浏览(176)

我尝试在搜索文档中的特定字段时获取该字段的值,例如:

use mongodb::{bson::{doc,Document},options::ClientOptions, Client};
//..
let client = Client::with_options(ClientOptions::parse("mongodb+srv://user:pass@cluster0.um0c2p7.mongodb.net/?retryWrites=true&w=majority").await.unwrap()).unwrap();
let coll = client.database("braq").collection("users");
let user  = coll.find_one(doc!{"user":"user1"},None).await.unwrap();
println!("Hello, {}!",user.user1);

我得到的错误:

#9 311.1 error[E0698]: type inside `async fn` body must be known in this context
#9 311.1   --> src/main.rs:46:35
#9 311.1 46 |     let db = client.database("braq").collection("users");
#9 311.1    |                                      ^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `collection`
#9 311.1 note: the type is part of the `async fn` body because of this `await`
#9 311.1   --> src/main.rs:47:50
#9 311.1 47 |     let deb  = db.find_one(doc!{"user":"user1"},None).await.unwrap();
#9 311.1    |                                                     ^^^^^^
#9 311.1 
------
 > [4/4] RUN cargo install --path .:
#9 311.1 46 |     let db = client.database("braq").collection("users");
#9 311.1    |                                      ^^^^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `collection`
#9 311.1 note: the type is part of the `async fn` body because of this `await`
#9 311.1   --> src/main.rs:47:50
#9 311.1 47 |     let deb  = db.find_one(doc{"user":"user1"},None).await.unwrap();
#9 311.1    |                                                     ^^^^^^

我怎样才能做到不出错呢?

3ks5zfa0

3ks5zfa01#

您收到的错误消息是因为您没有为集合提供泛型类型。请阅读有关它的详细信息here
如果您想使用bson::Document(正如您的标题所示;它也是集合中最通用的类型,允许您存储和检索任意文档,而不受mongodb本身所施加的限制之外的任何限制),您必须使用它提供的许多get方法之一。如果您希望字段user1是字符串,则可以使用Document::get_str方法,例如:

let coll = client.database("braq").collection::<Document>("users");
                                             // ^^^^^^^^ type of our collection 
let user: Document = coll.find_one(doc! {"user":"user1"}, None).await.unwrap().unwrap();
    
println!("Hello, {}!", user.get_str("user1").unwrap());

或者,你也可以告诉你的集合它存储的文档是由哪个具体的Rust类型构成的,它会负责将查询结果反序列化为你的Rust类型。唯一的限制是你的类型必须实现serde的Deserialize特征:

use serde::Deserialize;
    
#[derive(Deserialize)]
struct User {
    user1: String,
}
    
let coll = client.database("braq").collection::<User>("users");
                                             // ^^^^ type of our collection
let user: User = coll.find_one(doc! {"user":"user1"}, None).await.unwrap().unwrap();
    
println!("Hello, {}!", user.user1);

相关问题