【问题标题】:How to get collection of document from mongodb cursor?如何从 mongodb 游标中获取文档集合?
【发布时间】:2021-07-06 05:08:15
【问题描述】:

我有以下代码应该从 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&lt;Document&gt; 转换为Vec&lt;T&gt;,这是我第一次看到Cursor&lt;Document&gt;,我不知道它是什么。

更新
错误信息:

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 `()`

【问题讨论】:

  • 你得到的错误仅仅是因为你没有在函数结束时返回任何东西。
  • @kmdreko 如果这就是我想通过 cursor 变量返回 vec&lt;Vehicle&gt; 的原因。

标签: mongodb rust bson


【解决方案1】:

一个 mongodb Cursorfutures crate 实现 Stream。这是docs中提到的:

此外,Stream 具有的所有其他方法也可在 Cursor 上使用。这包括StreamExt 提供的所有功能,它提供了与标准库Iterator trait 类似的功能。例如,如果已知查询的结果数量很少,则将它们收集到向量中可能是有意义的:

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

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

这是一个工作示例

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![])
}

【讨论】:

  • 一个问题。是 Document = bson::Document 吗?,我收到一个错误:在 cursor 变量中无法识别collect()。 :“由于不满足的特征边界,无法在 mongodb::Cursor 上调用方法”
  • 你能在原始问题中包含完整的错误吗?我想我知道问题出在哪里,但我不能确定。
  • 我已更新我的答案以更具示范性。
  • 谢谢,您有效地解决了我的问题,但您认为它适用于具有较少字段的dto_struct 吗?反正原来的问题已经解决了,再次感谢。
猜你喜欢
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
相关资源
最近更新 更多