Help - some direction? Futures, mongodb, stream::collect()

I'm trying to figure out how to use the mongodb driver 1.1.1

I have not included code, because I am hoping just for a nudge in the right direction.

I've got a function with a client with a connection to the Database and collection (that seems to be fine), but when I try to use the supposed returned cursor from a find method, I am getting a future, not a cursor. Now I accept that that is how futures work, but I can't find any information in how to get the actual cursor. I need the future to complete and I can't seem to find anything that says how to do that.

I watched the rustfest barcelona video on async that suggests using task::block_on, but either that isn't right or more likely I am using it completely wrong.

Can kind soul please point me in the right direction? I'm spinning my wheels here feeling like I'm going to go insane.

Could you post your code where you're using block_on? That does sound like the right approach for your use-case, but it's hard to tell what's going wrong.

If you are not already using async/await for some other reason, I recommend using the mongodb::sync module, which does not require messing with block_on and the likes.

1 Like

Sorry, due to work conditions I have been afk for a couple days.
But I got it working! Turns out I forgot to await inside the task. I also decided not to use collect(). Here is the code that works(as in compiles and does reach out to the mongo db), it's really bad as I am just starting out, so feel free to point me to any improvements.

pub async fn get_data(datb: &str, col:&str, docu: Document)->Vec<String>{
let client = match Client::with_uri_str("mongodb://localhost:27017").await {
    Ok(c)=>c,
    Err(e)=>panic!("Could not reach client"),
};
let coll = client.database(datb).collection(col);
let mut cursor = match coll.find(docu,None).await{
    Ok(cursor)=>cursor,
    Err(e)=>panic!("Problem with the database"),
};
let mut docs= Vec::new();
while let Some(result) = cursor.next().await {
    match result {
        Ok(document) => {
            if let Some(title) = document.get("author").and_then(Bson::as_str) {
                docs.push(String::from(title));
            }  else {
                println!("no titles found");
            }
        }
        Err(e) => panic!("error getting data:{}",e ),
    }
}
docs
}

fn main() {
let data = task::block_on(async{get_data("library","books"|,doc!{"author":"test"}).await});
    println!("{:?}",data);
}

Whenever you have

match x {
    Ok(val) => do_something_with(val),
    Err(_) => panic!("oh no"),
}

you can instead use the shorter and more idiomatic

do_something_with(x.expect("oh no"))

See Result::expect and the book chapter on error handling. (There is also Option::expect, which works similarly.)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.