On this page, you can find frequently asked questions and their corresponding answers.
Tip
If you can't find an answer to your question on this page, see the Issues & Help page for information on how to report issues.
Why Do I Get Errors While Connecting to MongoDB?
If you have trouble connecting to a MongoDB deployment, see the Connection Troubleshooting guide for possible solutions.
How Does Connection Pooling Work in the Rust Driver?
Each server in your MongoDB cluster maintains a connection pool. You can access or manage the behavior of the connection pool by using an instance of a Client. Connection pools open sockets on demand to support concurrent operations in your multi-threaded application.
You can configure the following connection pool features:
- Maximum and minimum size, set by the - max_pool_sizeand- min_pool_sizeoptions
- Maximum number of connections that the pool creates in parallel, set by the - max_connectingoption
- Maximum idle time, set by the - max_idle_timeoption
For more information about connection pooling, see the Connection Pool section of the Performance Considerations guide.
How Do I Convert Between BSON and Rust Types?
The Rust driver and the BSON library use the Serde framework to perform
conversions between custom Rust types and BSON. You can add the serde
crate to your Cargo.toml file to access the functionality of the Serde framework.
For instructions on adding this crate, see serde
in the crates registry.
After you add the crate to your application, you can model the documents in a collection
by using a custom type instead of a BSON document. The following example includes the derive
attribute before the Vegetable struct definition, which instructs the driver to
perform the following actions when needed:
- Serialize the struct, which converts the struct to BSON 
- Deserialize BSON, which converts BSON data to your struct 
struct Vegetable {    // Add struct fields here } 
You can then create a Collection instance with your custom struct type as its
generic type parameter. The following example assigns a Collection instance
parameterized with the Vegetable type to the my_coll variable:
let my_coll: Collection<Vegetable> = client.database("db").collection("vegetables"); 
For more information about converting between BSON and Rust types, see the Data Modeling and Serialization guide and the Structuring Data with Serde in Rust MongoDB Developer Center article.
How Do I Fix Unsatisfied Trait Bounds Errors?
Trait bounds allow methods to restrict which types they accept as parameters
and what functionality those types must implement. For example, if you define
a method that accepts a generic type parameter and prints its value, the parameter
must implement the Display trait for printing purposes. The following example
defines the printer() method and specifies that its parameter must implement
Display:
fn printer<T: Display>(t: T) {    println!("{}", t); } 
When calling a method on a data type, you might encounter an error stating that
the method's trait bounds are not satisfied. For example, the driver might raise
the following error message when you call the try_next() method on a Cursor
instance:
error[E0599]: the method `try_next` exists for struct `mongodb::Cursor<T>`, but its trait bounds were not satisfied 
The Cursor<T> type only implements the Stream trait, which is required to access
the try_next() method, if the trait bounds for T are satisfied. Namely, T
must implement the DeserializeOwned trait, as specified in the Cursor API documentation. The following example replicates the
preceding error message by defining a custom Actor struct to model documents in the
actors collection. However, this struct does not implement the DeserializeOwned trait,
and using the try_next() method to iterate over Actor instances causes an error:
struct Actor {    name: String, } // Add setup code here let my_coll: Collection<Actor> = client.database("db").collection("actors"); let mut cursor = my_coll.find(doc! {}).await?; while let Some(result) = cursor.try_next().await? {      println!("{:?}", result);  }; 
To resolve the trait bounds error, identify the data type over which the cursor
iterates and ensure that this data type implements the DeserializeOwned trait.
You can use the derive attribute to apply the required trait bound.
Note
Deserialize and DeserializeOwned Traits
The serde crate provides derive macros to generate the implementation of
certain traits, including the Deserialize trait. However, this crate does not
offer a derive macro for the DeserializeOwned trait. Data types that implement
Deserialize without lifetime restrictions automatically implement DeserializeOwned,
so you can implement Deserialize to fulfill the DeserializeOwned trait bound.
The following example adjusts the Actor struct definition to implement Deserialize:
struct Actor {    name: String, } 
For more information about trait bounds, see the following resources:
How Do I Process a Value Wrapped in a Result or Option Enum?
Rust provides the Result and Option enums as safeguards for your application
code. Many methods offered by the Rust driver return values wrapped in one of these
two types.
The Result enum can return the following variants:
- Ok(T): wraps the value of the result of the operation
- Err(E): wraps an error value if the operation is unsuccessful
For example, the insert_one() method returns a Result type to wrap either a successful
response or an error.
To access the unwrapped result of insert_one(), use the ? operator. If the operation is
successful, the method returns the Ok(InsertOneResult) variant of the Result enum. In this
case, the ? operator unwraps the InsertOneResult value and assigns it to the insert_one_result
variable. If the operation is unsuccessful, the method returns the Err(E) enum variant, and the
? operator unwraps and returns the error value. The following code demonstrates the syntax for
using the ? operator while handling an insert operation result:
let insert_one_result = my_coll.insert_one(doc).await?; 
Alternatively, you can create a conditional to handle the unwrapped values of InsertOneResult.
The following code uses the match keyword to process the insert_one() result:
let insert_one_result = my_coll.insert_one(doc).await; match insert_one_result {    Ok(val) => {      println!("Document inserted with ID: {}", val.inserted_id);    },    Err(err) => {      println!("Operation not successful");    } } 
The Option enum can return the following variants:
- None: represents an empty value returned by an operation
- Some(T): wraps a non-empty return value
Some Rust driver methods return an Option type, such as the read_concern()
method. This method returns an Option that wraps either an empty value, if no read
concern exists, or a ReadConcern value.
To access the result of read_concern(), you can use the same match syntax as shown
in the preceding example to process the None and Some(T) variants. Alternatively, you
can use the if let syntax to process only the Some(T) variant. The following code unwraps
and prints the non-empty read_concern() return value, if it exists:
if let Some(rc) = my_coll.read_concern() {    println!("Read concern: {:?}", rc); } 
For more information about the Result and Option enums, see the following
resources in the Rust language documentation: