尝试使用MongoDB Rust官方驱动程序(alpha版)
总结听说MongoDB官方的Rust驱动程序(alpha版)已经发布了,所以我决定试一试。
虽然买了关于Rust的书籍,但一直没时间读,所以我从安装开始,花了大约半天的时间学习了用Rust编写MongoDB驱动所需的基本知识。在进行试验和纠错的同时,我也在写这篇文章,所以可能会有一些错误。希望借此机会能够真正开始学习Rust。
环境
- 
Windows 10
 
- 
- Windows 10
 
 
- 
- MongoDB Community版 4.2.2
 
 
- 
- rust 1.40.0
 
 
- 
- MongoDB rust
 
 
ドライバー 0.9.0 (alpha版)
https://crates.io/crates/mongodb
https://github.com/mongodb/mongo-rust-driver
bson 0.14.0
https://crates.io/crates/bson
https://github.com/mongodb/bson-rust
实施
在Cargo.toml中添加依赖项
[dependencies]
mongodb ="0.9.0"
bson = "0.14.0"
尝试运行文件中列出的代码。
use mongodb::{error::Result, options::{ClientOptions, FindOptions}, Client};
use bson::{doc, bson, Bson};
fn main() {
    let client = connect_mongo().expect("failed to connect");
    list_db(&client).expect("failed to list db names");
    list_collection(&client, "test").expect("failed to list collection names");
    insert_docs(&client).expect("failed to insert docs");
    find_docs(&client).expect("failed to find docs");
}
fn connect_mongo() -> Result<Client> {
    // Parse a connection string into an options struct.
    let mut client_options = ClientOptions::parse("mongodb://localhost:27017")?;
    // 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)?;
    Ok(client)
}
fn list_db(client: &Client) -> Result<()> {
    // List the names of the databases in that deployment.
    println!("------ print db --------");
    for db_name in client.list_database_names(None)? {
        println!("{}", db_name);
    }
    Ok(())
}
fn list_collection(client: &Client, dbname: &str) -> Result<()> {
    // Get a handle to a database.
    let db = client.database(dbname);
    // List the names of the collections in that database.
    println!("------ print collection ({}) --------", dbname);
    for collection_name in db.list_collection_names(None)? {
        println!("{}", collection_name);
    }
    Ok(())
}
fn insert_docs(client: &Client) -> Result<()> {
    // Get a handle to a collection in the database.
    let collection = client.database("test").collection("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 "test.books" collection.
    collection.insert_many(docs, None)?;
    Ok(())
}
fn find_docs(client: &Client) -> Result<()> {
    // Get a handle to a collection in the database.
    let collection = client.database("test").collection("books");
    // Query the documents 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 cursor = collection.find(filter, find_options)?;
    println!("------ print find  --------");
    // Iterate over the results of the cursor.
    for result in cursor {
        match result {
            Ok(document) => {
                if let Some(title) = document.get("title").and_then(Bson::as_str) {
                    println!("title: {}", title);
                }  else {
                    println!("no title found");
                }
            }
            Err(e) => return Err(e.into()),
        }
    }
    Ok(())
}
> cargo run
     Running `target\debug\mongorust.exe`
------ print db --------
admin
config
local
test
------ print collection (test) --------
col
system.profile
books
col2
------ print find  --------
title: 1984
title: Animal Farm
最终
我最初以为只要复制粘贴代码就可以立即运行,但我对?运算符、Result的使用以及client变量的所有权不太了解,所以花了很长时间。由于没有处理结构体的示例,所以我会继续研究。
链接使用MongoDB官方的Rust驱动程序(Alpha版本)进行尝试(2)(使用结构体)。
        
[dependencies]
mongodb ="0.9.0"
bson = "0.14.0"
尝试运行文件中列出的代码。
use mongodb::{error::Result, options::{ClientOptions, FindOptions}, Client};
use bson::{doc, bson, Bson};
fn main() {
    let client = connect_mongo().expect("failed to connect");
    list_db(&client).expect("failed to list db names");
    list_collection(&client, "test").expect("failed to list collection names");
    insert_docs(&client).expect("failed to insert docs");
    find_docs(&client).expect("failed to find docs");
}
fn connect_mongo() -> Result<Client> {
    // Parse a connection string into an options struct.
    let mut client_options = ClientOptions::parse("mongodb://localhost:27017")?;
    // 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)?;
    Ok(client)
}
fn list_db(client: &Client) -> Result<()> {
    // List the names of the databases in that deployment.
    println!("------ print db --------");
    for db_name in client.list_database_names(None)? {
        println!("{}", db_name);
    }
    Ok(())
}
fn list_collection(client: &Client, dbname: &str) -> Result<()> {
    // Get a handle to a database.
    let db = client.database(dbname);
    // List the names of the collections in that database.
    println!("------ print collection ({}) --------", dbname);
    for collection_name in db.list_collection_names(None)? {
        println!("{}", collection_name);
    }
    Ok(())
}
fn insert_docs(client: &Client) -> Result<()> {
    // Get a handle to a collection in the database.
    let collection = client.database("test").collection("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 "test.books" collection.
    collection.insert_many(docs, None)?;
    Ok(())
}
fn find_docs(client: &Client) -> Result<()> {
    // Get a handle to a collection in the database.
    let collection = client.database("test").collection("books");
    // Query the documents 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 cursor = collection.find(filter, find_options)?;
    println!("------ print find  --------");
    // Iterate over the results of the cursor.
    for result in cursor {
        match result {
            Ok(document) => {
                if let Some(title) = document.get("title").and_then(Bson::as_str) {
                    println!("title: {}", title);
                }  else {
                    println!("no title found");
                }
            }
            Err(e) => return Err(e.into()),
        }
    }
    Ok(())
}
> cargo run
     Running `target\debug\mongorust.exe`
------ print db --------
admin
config
local
test
------ print collection (test) --------
col
system.profile
books
col2
------ print find  --------
title: 1984
title: Animal Farm
最终
我最初以为只要复制粘贴代码就可以立即运行,但我对?运算符、Result的使用以及client变量的所有权不太了解,所以花了很长时间。由于没有处理结构体的示例,所以我会继续研究。
链接使用MongoDB官方的Rust驱动程序(Alpha版本)进行尝试(2)(使用结构体)。
        
use mongodb::{error::Result, options::{ClientOptions, FindOptions}, Client};
use bson::{doc, bson, Bson};
fn main() {
    let client = connect_mongo().expect("failed to connect");
    list_db(&client).expect("failed to list db names");
    list_collection(&client, "test").expect("failed to list collection names");
    insert_docs(&client).expect("failed to insert docs");
    find_docs(&client).expect("failed to find docs");
}
fn connect_mongo() -> Result<Client> {
    // Parse a connection string into an options struct.
    let mut client_options = ClientOptions::parse("mongodb://localhost:27017")?;
    // 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)?;
    Ok(client)
}
fn list_db(client: &Client) -> Result<()> {
    // List the names of the databases in that deployment.
    println!("------ print db --------");
    for db_name in client.list_database_names(None)? {
        println!("{}", db_name);
    }
    Ok(())
}
fn list_collection(client: &Client, dbname: &str) -> Result<()> {
    // Get a handle to a database.
    let db = client.database(dbname);
    // List the names of the collections in that database.
    println!("------ print collection ({}) --------", dbname);
    for collection_name in db.list_collection_names(None)? {
        println!("{}", collection_name);
    }
    Ok(())
}
fn insert_docs(client: &Client) -> Result<()> {
    // Get a handle to a collection in the database.
    let collection = client.database("test").collection("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 "test.books" collection.
    collection.insert_many(docs, None)?;
    Ok(())
}
fn find_docs(client: &Client) -> Result<()> {
    // Get a handle to a collection in the database.
    let collection = client.database("test").collection("books");
    // Query the documents 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 cursor = collection.find(filter, find_options)?;
    println!("------ print find  --------");
    // Iterate over the results of the cursor.
    for result in cursor {
        match result {
            Ok(document) => {
                if let Some(title) = document.get("title").and_then(Bson::as_str) {
                    println!("title: {}", title);
                }  else {
                    println!("no title found");
                }
            }
            Err(e) => return Err(e.into()),
        }
    }
    Ok(())
}
> cargo run
     Running `target\debug\mongorust.exe`
------ print db --------
admin
config
local
test
------ print collection (test) --------
col
system.profile
books
col2
------ print find  --------
title: 1984
title: Animal Farm
我最初以为只要复制粘贴代码就可以立即运行,但我对?运算符、Result的使用以及client变量的所有权不太了解,所以花了很长时间。由于没有处理结构体的示例,所以我会继续研究。