Expand description
This crate contains the officially supported MongoDB Rust driver, a
client side library that can be used to interact with MongoDB deployments
in Rust applications. It uses the bson
crate for BSON support.
The driver contains a fully async API that supports either tokio
(default)
or async-std
, depending on the feature flags set. The driver also has
a sync API that may be enabled via the "sync"
feature flag.
Installation
Requirements
- Rust 1.51+
- MongoDB 3.6+
Importing
The driver is available on crates.io. To use the driver in
your application, simply add it to your project’s Cargo.toml
.
[dependencies]
mongodb = "2.2.1"
Configuring the async runtime
The driver supports both of the most popular async runtime crates, namely
tokio
and async-std
. By
default, the driver will use tokio
, but you can explicitly choose
a runtime by specifying one of "tokio-runtime"
or "async-std-runtime"
feature flags in your
Cargo.toml
.
For example, to instruct the driver to work with async-std
,
add the following to your Cargo.toml
:
[dependencies.mongodb]
version = "2.2.1"
default-features = false
features = ["async-std-runtime"]
Enabling the sync API
The driver also provides a blocking sync API. To enable this, add the "sync"
feature to your
Cargo.toml
:
[dependencies.mongodb]
version = "2.2.1"
default-features = false
features = ["sync"]
Note: if the sync API is enabled, the async-specific types will be privatized (e.g.
mongodb::Client
). The sync-specific types can be imported from mongodb::sync
(e.g.
mongodb::sync::Client
).
All Feature flags
Feature | Description | Extra dependencies | Default |
---|---|---|---|
tokio-runtime | Enable support for the tokio async runtime | tokio 1.0 with the full feature | yes |
async-std-runtime | Enable support for the async-std runtime | async-std 1.0 | no |
sync | Expose the synchronous API (mongodb::sync ). This flag cannot be used in conjunction with either of the async runtime feature flags. | async-std 1.0 | no |
aws-auth | Enable support for the MONGODB-AWS authentication mechanism. | reqwest 0.11 | no |
bson-uuid-0_8 | Enable support for v0.8 of the uuid crate in the public API of the re-exported bson crate. | n/a | no |
bson-chrono-0_4 | Enable support for v0.4 of the chrono crate in the public API of the re-exported bson crate. | n/a | no |
bson-serde_with | Enable support for the serde_with crate in the public API of the re-exported bson crate. | serde_with 1.0 | no |
zlib-compression | Enable support for compressing messages with zlib | flate2 1.0 | no |
zstd-compression | Enable support for compressing messages with zstd . This flag requires Rust version 1.54. | zstd 0.9.0 | no |
snappy-compression | Enable support for compressing messages with snappy | snap 1.0.5 | no |
openssl-tls | Switch TLS connection handling to use ‘openssl’. | openssl 0.10.38 | no |
Example Usage
Using the async API
Connecting to a MongoDB deployment
use mongodb::{Client, options::ClientOptions};
// Parse a connection string into an options struct.
let mut client_options = ClientOptions::parse("mongodb://localhost:27017").await?;
// Manually set an option.
client_options.app_name = Some("My App".to_string());
// Get a handle to the deployment.
let client = Client::with_options(client_options)?;
// List the names of the databases in that deployment.
for db_name in client.list_database_names(None, None).await? {
println!("{}", db_name);
}
Getting a handle to a database
// Get a handle to a database.
let db = client.database("mydb");
// List the names of the collections in that database.
for collection_name in db.list_collection_names(None).await? {
println!("{}", collection_name);
}
Inserting documents into a collection
use mongodb::bson::{doc, Document};
// Get a handle to a collection in the database.
let collection = db.collection::<Document>("books");
let docs = vec![
doc! { "title": "1984", "author": "George Orwell" },
doc! { "title": "Animal Farm", "author": "George Orwell" },
doc! { "title": "The Great Gatsby", "author": "F. Scott Fitzgerald" },
];
// Insert some documents into the "mydb.books" collection.
collection.insert_many(docs, None).await?;
A Collection
can be parameterized with any type that implements the
Serialize
and Deserialize
traits from the serde
crate,
not just Document
:
serde = { version = "1.0", features = ["derive"] }
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Book {
title: String,
author: String,
}
// Get a handle to a collection of `Book`.
let typed_collection = db.collection::<Book>("books");
let books = vec![
Book {
title: "The Grapes of Wrath".to_string(),
author: "John Steinbeck".to_string(),
},
Book {
title: "To Kill a Mockingbird".to_string(),
author: "Harper Lee".to_string(),
},
];
// Insert the books into "mydb.books" collection, no manual conversion to BSON necessary.
typed_collection.insert_many(books, None).await?;
Finding documents in a collection
Results from queries are generally returned via Cursor
, a struct which streams
the results back from the server as requested. The Cursor
type implements the
Stream
trait from
the futures
crate, and in order to access its streaming
functionality you need to import at least one of the
StreamExt
or
TryStreamExt
traits.
futures = "0.3"
// This trait is required to use `try_next()` on the cursor
use futures::stream::TryStreamExt;
use mongodb::{bson::doc, options::FindOptions};
// Query the books in the collection with a filter and an option.
let filter = doc! { "author": "George Orwell" };
let find_options = FindOptions::builder().sort(doc! { "title": 1 }).build();
let mut cursor = typed_collection.find(filter, find_options).await?;
// Iterate over the results of the cursor.
while let Some(book) = cursor.try_next().await? {
println!("title: {}", book.title);
}
Using the sync API
The driver also provides a blocking sync API. See the Installation section for instructions on how to enable it.
The various sync-specific types are found in the mongodb::sync
submodule rather than in the
crate’s top level like in the async API. The sync API calls through to the async API internally
though, so it looks and behaves similarly to it.
use mongodb::{
bson::doc,
sync::Client,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Book {
title: String,
author: String,
}
let client = Client::with_uri_str("mongodb://localhost:27017")?;
let database = client.database("mydb");
let collection = database.collection::<Book>("books");
let docs = vec![
Book {
title: "1984".to_string(),
author: "George Orwell".to_string(),
},
Book {
title: "Animal Farm".to_string(),
author: "George Orwell".to_string(),
},
Book {
title: "The Great Gatsby".to_string(),
author: "F. Scott Fitzgerald".to_string(),
},
];
// Insert some books into the "mydb.books" collection.
collection.insert_many(docs, None)?;
let cursor = collection.find(doc! { "author": "George Orwell" }, None)?;
for result in cursor {
println!("title: {}", result?.title);
}
Warning about timeouts / cancellation
In async Rust, it is common to implement cancellation and timeouts by dropping a future after a
certain period of time instead of polling it to completion. This is how
tokio::time::timeout
works, for
example. However, doing this with futures returned by the driver can leave the driver’s internals in
an inconsistent state, which may lead to unpredictable or incorrect behavior (see RUST-937 for more
details). As such, it is highly recommended to poll all futures returned from the driver to
completion. In order to still use timeout mechanisms like tokio::time::timeout
with the driver,
one option is to spawn tasks and time out on their
JoinHandle
futures instead of on
the driver’s futures directly. This will ensure the driver’s futures will always be completely polled
while also allowing the application to continue in the event of a timeout.
e.g.
let collection = client.database("foo").collection("bar");
let handle = tokio::task::spawn(async move {
collection.insert_one(doc! { "x": 1 }, None).await
});
tokio::time::timeout(Duration::from_secs(5), handle).await???;
Minimum supported Rust version (MSRV)
The MSRV for this crate is currently 1.51.0. This will be rarely be increased, and if it ever is, it will only happen in a minor or major version release.
Re-exports
pub use {{root}}::bson;
Modules
Contains the functionality for change streams.
Contains the Error
and Result
types that mongodb
uses.
Contains the events and functionality for monitoring internal Client
behavior.
Contains all of the types needed to specify options to MongoDB operations.
Contains the types of results returned by CRUD operations.
sync
or tokio-sync
Contains the sync API. This is only available when the sync
feature is enabled.
Structs
This is the main entry point for the API. A Client
is used to connect to a MongoDB cluster.
By default, it will monitor the topology of the cluster, keeping track of any changes, such
as servers being added or removed.
A MongoDB client session. This struct represents a logical session used for ordering sequential
operations. To create a ClientSession
, call start_session
on a Client
.
Struct modeling a cluster time reported by the server.
Collection
is the client-side abstraction of a MongoDB Collection. It can be used to
perform collection-level operations such as CRUD operations. A Collection
can be obtained
through a Database
by calling either
Database::collection
or
Database::collection_with_options
.
A Cursor
streams the result of a query. When a query is made, the returned Cursor
will
contain the first batch of results from the server; the individual results will then be returned
as the Cursor
is iterated. When the batch is exhausted and if there are more results, the
Cursor
will fetch the next batch of documents, and so forth until the results are exhausted.
Note that because of this batching, additional network I/O may occur on any given call to
next
. Because of this, a Cursor
iterates over Result<T>
items rather than
simply T
items.
Database
is the client-side abstraction of a MongoDB database. It can be used to perform
database-level operations or to obtain handles to specific collections within the database. A
Database
can only be obtained through a Client
by calling either
Client::database
or
Client::database_with_options
.
Specifies the fields and options for an index. For more information, see the documentation.
A struct modeling the canonical name for a collection in MongoDB.
A description of the most up-to-date information known about a server. Further details can be found in the Server Discovery and Monitoring specification.
A SessionCursor
is a cursor that was created with a ClientSession
that must be iterated
using one. To iterate, use SessionCursor::next
or retrieve a SessionCursorStream
using
SessionCursor::stream
:
A type that implements Stream
which can be used to
stream the results of a SessionCursor
. Returned from SessionCursor::stream
.
Enums
Enum representing the possible types of servers that the driver can connect to.
The possible types for a topology.