如何从 mongodb 游标获取文档集合?

How to get collection of document from mongodb cursor?

我有以下代码,它应该 return 来自 mongodb.

的文档列表
struct Vehicle{
    id: String,
    name: String
}

pub async fn list_all() -> Vec<Vehicle>{
    let mongodb = connection_bd::connection_mongodb().await;
    let mongodb_collection = mongodb.collection("Vehicle");
    let result = mongodb_collection.find(None, None).await; //result: Result<Cursor<Document>, Error>
    let cursor = match result { //cursor: Cursor<Document>
        Ok(x) => x,
        Err(_) => return vec![]
    };
    //...
}

我无法完成代码,因为我不知道如何将 Cursor<Document> 转换为 Vec<T>,这是我第一次看到 Cursor<Document>,我不知道是什么是的。

已更新
错误信息:

error[E0308]: mismatched types
  --> src\vehicle_repo.rs:77:40
   |
77 |   pub async fn list_all() -> Vec<Vehicle>{
   |  ________________________________________^
78 | |     let mongodb = connection_bd::connection_mongodb().await;
79 | |     let mongodb_collection = mongodb.collection("Vehicle");
...  |
84 | |     };
85 | | }
   | |_^ expected struct `Vec`, found `()`
   |
   = note: expected struct `Vec<Vehicle>`
           found unit type `()`

A mongodb Cursorfutures crate. This is mentioned in the docs:

实现 Stream

Additionally, all the other methods that a Stream has are available on Cursor as well. This includes all of the functionality provided by StreamExt, which provides similar functionality to the standard library Iterator trait. For instance, if the number of results from a query is known to be small, it might make sense to collect them into a vector:

let results: Vec<Result<Document>> = cursor.collect().await;

我实际上建议使用 TryStreamExt 特征中的 try_collect() 函数来获得 Result<Vec<Document>>。然后你可以使用 unwrap_or_else() 到 return 列表。您还应该使用 collection_with_type() 方法来获取集合,以便您的结果将自动反序列化为正确的类型,而不仅仅是 Document (只要确保它实现了 Debug, SerializeDeserialize).

这是一个工作示例

use futures::TryStreamExt;
use mongodb::Client;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
struct Vehicle {
    id: String,
    name: String,
}

async fn list_all() -> Vec<Vehicle> {
    let client = Client::with_uri_str("mongodb://example.com").await.unwrap();
    let database = client.database("test");
    let collection = database.collection_with_type::<Vehicle>("vehicles");
    let cursor = match collection.find(None, None).await {
        Ok(cursor) => cursor,
        Err(_) => return vec![],
    };

    cursor.try_collect().await.unwrap_or_else(|_| vec![])
}