如何在 Rust 中使用 Mongodb::cursor?

Den*_*Hiu 6 mongodb rust

这是一个非常简单的项目,用于学习如何将 mongodb 与 Rust 结合使用。我在这里使用官方 mongodb 驱动程序:https://github.com/mongodb/mongo-rust-driver。问题是,如果我使用aggregate,我无法读取结果

// main.rs
use mongodb::bson::{doc, Bson};
use mongodb::{options::AggregateOptions, options::ClientOptions, Client};
use std::error::Error;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {

   // Load the MongoDB connection string:
   let client_uri = "mongodb://127.0.0.1:27017";

   // A Client is needed to connect to MongoDB:
   let mut options = ClientOptions::parse(&client_uri).await?;
   options.app_name = Some("testing".to_string());
   let client = Client::with_options(options)?;
   
   // get the collection here
   let items = client.database("my_database").collection("inventory");

   // aggregate options and pipeline
   let pipeline = vec![doc! {"$match": {"name": "FOO"}}];
   let options = AggregateOptions::builder().allow_disk_use(true).build();

   // I'm using tokio for async-await library
   let data = items
      .aggregate(pipeline, options)
      .await
      .map_err(|e| println!("{}", e));

    // data is a Result<mongodb::Cursor> type
    match data {
       Ok(cursor) => {
        
          // I want to iterate the returned documents here
          // this doesn't compiles
          while let Some(doc) = cursor.next().await {
              println!("{}", doc?)
          }
       },
       Err(e) => println!("{:?}", e),
}
Run Code Online (Sandbox Code Playgroud)

上面的代码返回一个错误。它抱怨光标没有任何next()功能。

 while let Some(doc) = cursor.next().await {
   |                          ^^^^ method not found in `mongodb::Cursor`
Run Code Online (Sandbox Code Playgroud)

我在这里阅读了 mongodb::Cursor 的手册:https://docs.rs/mongodb/1.2.1/mongodb/struct.Cursor.html

和这里的聚合函数https://docs.rs/mongodb/1.2.1/mongodb/struct.Collection.html#method.aggregate

正如您所看到的,聚合方法应该返回Result<Cursor>。正如手册所述:

游标可以像任何其他流一样使用。最简单的方法就是迭代它生成的文档:

while let Some(doc) = cursor.next().await {
  println!("{}", doc?)
}
Run Code Online (Sandbox Code Playgroud)

那么为什么它不起作用呢?

我的依赖项Cargo.toml

[dependencies]
tokio = { version = "0.2", features = ["macros", "rt-threaded"]  }
serde = { version = "1.0", features = ["derive"] }
mongodb = "1.2.0"
Run Code Online (Sandbox Code Playgroud)

如果我打印光标println!("{:?}", cursor);。它包含数据在里面。如何从这个游标中取出数据?

Den*_*Hiu 3

我找到了!只需添加use tokio::stream::StreamExt;到文件顶部,其余的就可以了。

...Stream 具有的所有其他方法也可在 Cursor 上使用。这包括 StreamExt 提供的所有功能,它提供与标准库 Iterator 特征类似的功能。

// main.rs
use mongodb::bson::{doc, Bson};
use mongodb::{options::AggregateOptions, options::ClientOptions, Client};
use std::error::Error;
use tokio;

// don't forget this!
use tokio::stream::StreamExt;
Run Code Online (Sandbox Code Playgroud)