Démarrage rapide : opérationnel avec Rust et MongoDB

Cet article de démarrage rapide vous aidera à connecter votre application Rust à un cluster MongoDB. Il vous montrera ensuite comment effectuer des opérations de création, de lecture, de mise à jour et de suppression (CRUD) sur un ensemble. Enfin, il montrera comment utiliser serde pour mapper entre les documents BSON de MongoDB et les structures Rust.

Série Outils & Versions

Cette série suppose que vous disposez d'une version récente de la chaîne d'outils Rust (v1.44+) et que vous êtes à l'aise avec la syntaxe Rust. Cela suppose également que vous êtes parfaitement à l'aise avec la ligne de commande et votre éditeur de code préféré.

Rust est un langage de programmation système puissant avec des performances élevées et une faible utilisation de la mémoire, adapté à une variété de tâches. Bien qu'il s'agisse actuellement d'un langage de niche pour travailler avec des données, sa popularité augmente rapidement !

Si vous utilisez Rust et que vous souhaitez travailler avec MongoDB, cette série de blogs est le point de départ ! Je vais vous montrer comment faire les choses suivantes :

Installez le pilote MongoDB Rust. Le pilote Rust est un bucket mongodb qui vous permet de communiquer avec un cluster MongoDB.

Connectez-vous à une instance MongoDB.

Créez, lisez, mettez à jour et supprimez des documents (CRUD) dans votre base de données.

Les articles de blog ultérieurs de cette série couvriront des sujets tels que Change Streams , Transactions et l' incroyable fonctionnalité Aggregation Pipeline qui vous permet d'exécuter des requêtes avancées sur vos données.

Conditions préalables

Je suppose que vous avez une connaissance pratique de Rust. Je n'utiliserai aucun code Rust compliqué - il s'agit d'un didacticiel MongoDB, pas d'un didacticiel Rust - mais vous voudrez au moins connaître les bases de la gestion des erreurs et de l'emprunt dans Rust ! Vous voudrez peut-être courir rustup updatesinon depuis mars 2020 car je travaillerai sur une version récente.

Vous aurez besoin des éléments suivants :

Chaîne d'outils Rust mise à jour, version 1.44+. Je recommande de l'installer avec Rustup si vous n'avez pas .

Un éditeur de code de votre choix. Je recommande d'utiliser IntelliJ Rust ou VS Code gratuitement avec le plugin Rust officiel

Le pilote MongoDB Rust utilise Tokio par défaut - et ce didacticiel le fera également. Si vous souhaitez exécuter sous async-std ou de manière synchrone, les modifications sont simples. je les couvrirai à la fin

Créez votre base de données

Vous utiliserez MongoDB Atlas pour héberger un cluster MongoDB, vous n'avez donc pas à vous soucier de la configuration de MongoDB lui-même.

Commencez avec un cluster M0 sur Atlas . C'est gratuit pour toujours et c'est le moyen le plus simple d'essayer les étapes de cette série de blogs. Vous n'aurez même pas besoin de fournir les détails de paiement.

Vous devrez créer un nouveau cluster et le charger avec des exemples de données en suivant ces étapes : 

  • Cliquez sur "Commencer gratuitement" sur la page d'accueil de MongoDB.
  • Entrez vos coordonnées ou inscrivez-vous simplement avec un compte Google si vous en avez un.
  • Accepter les conditions d'utilisation
  • Créez un cluster de démarrage .

  - Choisissez le même fournisseur de cloud que vous avez utilisé ou laissez-le tel quel. Choisissez un domaine qui vous convient.

  - Vous pouvez modifier le nom du cluster si vous le souhaitez. J'ai appelé "RustQuickstart".

Le provisionnement de votre cluster prendra quelques minutes. En attendant, vous pouvez passer à l'étape suivante.

Démarrez votre projet

Dans votre terminal, accédez au répertoire où vous conservez vos projets de chiffrement et exécutez la commande suivante :

cargo new --bin rust_quickstart

Cela créera un nouveau dossier appelé rust_quickstartcontenant un nouveau projet presque vide. Dans le dossier, ouvrez Cargo.tomlet modifiez la [dependencies]section pour qu'elle ressemble à ceci :

[dependencies]
mongodb = "1.2.0"

Vous pouvez maintenant télécharger et créer des dépendances en exécutant :

cargo run

Vous verrez beaucoup de dépendances téléchargées et compilées. Ne vous inquiétez pas, la plupart de ces problèmes ne se produisent que la première fois que vous l'exécutez ! Enfin, si tout se passe bien, il affichera "Hello, World!" dans votre tableau de bord.

Configurer votre instance MongoDB

Votre cluster MongoDB devrait être opérationnel en un rien de temps, vous pouvez donc continuer et configurer votre base de données pour les étapes suivantes.

Dans l'interface Web d'Atlas, vous verrez un bouton vert en bas à gauche de l'écran qui dit "Commencer". Si vous cliquez dessus, il affichera une liste de contrôle des étapes pour configurer votre base de données. Cliquez sur chaque élément de la liste (y compris l'élément facultatif « Charger des données d'échantillon ») et il vous guidera à travers les étapes pour le configurer.

Créer un utilisateur

En suivant les étapes "Mise en route", créez un utilisateur avec "Accès en lecture et en écriture à n'importe quelle base de données". Vous pouvez lui donner un nom d'utilisateur et un mot de passe de votre choix - notez-les, vous en aurez besoin dans une minute. Utilisez le bouton « générer automatiquement des mots de passe sécurisés » pour vous assurer que vous disposez d'un mot de passe aléatoire long qui peut également être collé en toute sécurité dans votre chaîne de connexion ultérieurement.

Autoriser l'adresse IP

Lors du déploiement d'une application avec des données sensibles, vous ne devez autoriser que l'adresse IP du serveur qui doit se connecter à votre base de données. Cliquez sur le bouton « Ajouter une adresse IP », puis « Ajouter une adresse IP existante » et enfin, « Confirmer ». Vous pouvez également définir une limite de temps pour les entrées de la liste d'accès, pour plus de sécurité. Notez que parfois votre adresse IP peut changer, donc si vous perdez la connectivité à votre cluster MongoDB au cours de ce didacticiel, revenez en arrière et répétez ces étapes.

Se connecter à MongoDB

Vous avez maintenant compris le but de ce didacticiel : connectez votre code Rust à la base de données MongoDB ! La dernière étape de la liste de contrôle « Commencer » est « Connexion à votre cluster ». Sélectionnez "Connectez vos applications".

Normalement, dans la boîte de dialogue qui s'affiche, vous sélectionnez "Rust" dans le menu "Pilote", mais comme le pilote Rust vient de sortir, il se peut qu'il ne figure pas dans la liste ! Vous devez choisir "Python" avec la version "3.6 ou ultérieure".

Assurez-vous que l'étape 2 a coché "Chaîne de connexion uniquement" et appuyez sur le bouton "Copier" pour copier l'URL dans votre feuille de collage (il suffit de la stocker dans un fichier texte). Collez-le au même endroit où vous avez enregistré votre nom d'utilisateur et votre mot de passe. Notez que l'URL <password>agit comme un espace réservé pour votre mot de passe. Vous devez coller votre mot de passe ici, en remplaçant tout l'espace réservé, y compris les caractères '<' et '>'.

De retour dans votre projet Rust, ouvrez main.rset remplacez le contenu par ce qui suit :

use mongodb::bson::{self, doc, Bson};
use std::env;
use std::error::Error;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
   // Load the MongoDB connection string from an environment variable:
   let client_uri =
      env::var("MONGODB_URI").expect("You must set the MONGODB_URI environment var!");

   // A Client is needed to connect to MongoDB:
   // An extra line of code to work around a DNS issue on Windows:
   let options =
      ClientOptions::parse_with_resolver_config(&client_uri, ResolverConfig::cloudflare())
         .await?;
   let client = mongodb::Client::with_options(options)?;

   // Print the databases in our MongoDB cluster:
   println!("Databases:");
   for name in client.list_database_names(None, None).await? {
      println!("- {}", name);
   }

   Ok(())
}

Pour l'exécuter, vous devez définir la variable d'environnement MONGODB_URI sur la chaîne de connexion que vous avez obtenue ci-dessus. Exécutez l'une des actions suivantes dans la fenêtre de votre terminal, en fonction de votre plate-forme :

# Unix (including MacOS):
export MONGODB_URI='mongodb+srv://yourusername:yourpasswordgoeshere@rustquickstart-123ab.mongodb.net/test?retryWrites=true&w=majority'

# Windows CMD shell:
set MONGODB_URI='mongodb+srv://yourusername:yourpasswordgoeshere@rustquickstart-123ab.mongodb.net/test?retryWrites=true&w=majority'

# Powershell:
$Env:MONGODB_URI='mongodb+srv://yourusername:yourpasswordgoeshere@rustquickstart-123ab.mongodb.net/test?retryWrites=true&w=majority'

Une fois cela fait, vous pouvez cargo runécrire ce code et le résultat ressemblera à ceci :

$ cargo run
   Compiling rust_quickstart v0.0.1 (/Users/judy2k/development/rust_quickstart)
   Finished dev [unoptimized + debuginfo] target(s) in 3.35s
   Running `target/debug/rust_quickstart`
Database: sample_airbnb
Database: sample_analytics
Database: sample_geospatial
Database: sample_mflix
Database: sample_supplies
Database: sample_training
Database: sample_weatherdata
Database: admin
Database: local

Toutes nos félicitations! Vous venez de connecter votre programme Rust à MongoDB et d'énumérer les bases de données de votre cluster. Si vous ne voyez pas cette liste, vous n'avez probablement pas chargé avec succès les exemples de données dans votre cluster - vous voudrez revenir quelques étapes en arrière jusqu'à ce que l'exécution de cette commande affiche la liste ci-dessus.

BSON - Comment MongoDB comprend les données

Avant de continuer à interroger et à mettre à jour votre base de données, il serait utile d'avoir une vue d'ensemble de BSON et de ses liens avec MongoDB. BSON est le format de données binaire utilisé par MongoDB pour stocker toutes vos données. BSON est également le format utilisé par le langage de requête MongoDB et les pipelines d'agrégation (nous en parlerons plus tard).

Il est similaire à JSON et traite tous les mêmes types de base, tels que les nombres, les chaînes, les tableaux et les objets (appelés Documents dans BSON), mais BSON prend en charge plus de types que JSON. Cela inclut des choses comme les dates et les décimales, et il a un type ObjectId spécial couramment utilisé pour identifier les documents dans une collection MongoDB. Étant donné que BSON est un format binaire, il n'est pas lisible par l'homme - généralement, lorsqu'il est imprimé à l'écran, il ressemblera à JSON.

En raison de la non-concordance entre le schéma dynamique de BSON et le système de type statique de Rust, la gestion de BSON dans Rust peut être difficile. Heureusement, bsonbins fournit un certain nombre d'outils utiles pour gérer les données BSON, y compris des doc!macros pour générer des documents BSON, et il implémente serde pour la sérialisation et les capacités de décodage entre les structures Rust et les données, qu'elles soient BSON.

Créez une structure de document avec une doc!macro qui ressemble à ceci :

let new_doc = doc! {
   "title": "Parasite",
   "year": 2020,
   "plot": "A poor family, the Kims, con their way into becoming the servants of a rich family, the Parks. But their easy life gets complicated when their deception is threatened with exposure.",
   "released": Utc.ymd(2020, 2, 7).and_hms(0, 0, 0),
};

Si vous utilisez println!pour imprimer la valeur de new_docsur la console, vous verrez quelque chose comme ceci :

{ title: "Parasite", year: 2020, plot: "A poor family, the Kims, con their way into becoming the servants of a rich family, the Parks. But their easy life gets complicated when their deception is threatened with exposure.", released: Date("2020-02-07 00:00:00 UTC") }

(Par ailleurs, Parasite est un film absolument incroyable. Ce n'est pas dans la base de données avec laquelle vous allez travailler car il est sorti en 2020 mais l'ensemble de données a été mis à jour pour la dernière fois en 2015)

Bien que la sortie ci-dessus ressemble un peu à JSON, c'est ainsi que la bibliothèque BSON implémente le Displaytrait. Les données sont toujours traitées comme des données binaires.

Créer un document

Les exemples suivants utilisent tous l' ensemble de données sample_mflix que vous avez chargé dans votre cluster Atlas. Il contient une collection intéressante appelée movies, avec des détails sur tous les téléchargements de films avec des sorties remontant à 1903, à partir de la base de données IMDB.

Le type de client vous permet d'obtenir une liste des bases de données de votre cluster, mais pas grand-chose d'autre. Pour vraiment commencer à travailler avec des données, vous aurez besoin d' une base de données utilisant un client databaseou des database_with_optionsméthodes. Vous le ferez dans la section suivante.

Le code de la dernière section crée le document en mémoire et vous allez maintenant l'enregistrer dans la base de données du film. La première étape avant de faire quoi que ce soit avec une collection MongoDB est d'obtenir un objet Collection de votre base de données. Cela se fait comme suit:

// Get the 'movies' collection from the 'sample_mflix' database:
let movies = client.database("sample_mflix").collection("movies");

Si vous avez parcouru la collection de films à l'aide de Compass ou de l'onglet "Collection" d'Atlas, vous constaterez que la plupart des enregistrements ont plus de champs que le document que j'ai créé ci-dessus à l'aide de la doc!macro. Parce que MongoDB n'applique pas de schéma dans la collection par défaut, c'est parfaitement bien et je viens de réduire le nombre de champs pour la lisibilité. Une fois que vous avez une référence à votre collection MongoDB, vous pouvez utiliser insert_onela méthode pour insérer un seul document :

let insert_result = movies.insert_one(new_doc.clone(), None).await?;
println!("New document ID: {}", insert_result.inserted_id);

Les insert_oneméthodes renvoient un type Result<InsertOneResult>qui peut être utilisé pour identifier tout problème d'insertion de document et peut être utilisé pour trouver l'identifiant généré pour les nouveaux documents dans MongoDB. Si vous ajoutez ce code à votre fonction principale, lorsque vous l'exécutez, vous verrez quelque chose comme ceci :

New document ID: ObjectId("5e835f3000415b720028b0ad")

Ce code insérera un single Documentdans une collection. Si vous souhaitez insérer de nombreux documents en bloc, il est plus efficace d'utiliser l' insert_manyobtention d'un IntoIteratordocument à insérer dans la collection.

Obtenir des données d'une collection

Comme je ne connais aucun autre document dans la collection nommée Parasite, vous pouvez le rechercher par titre en utilisant le code suivant, au lieu de l'ID que vous avez récupéré lors de l'insertion de l'enregistrement :

// Look up one document:
let movie = movies
   .find_one(
      doc! {
            "title": "Parasite"
      },
      None,
   ).await?
   .expect("Missing 'Parasite' document.");
println!("Movie: {}", movie);

Ce code se traduira par ce qui suit :

Movie: { _id: ObjectId("5e835f3000415b720028b0ad"), title: "Parasite", year: 2020, plot: "A poor family, the Kims, con their way into becoming the servants of a rich family, the Parks. But their easy life gets complicated when their deception is threatened with exposure.", released: Date("2020-02-07 00:00:00 UTC") }

Il est très similaire à la sortie ci-dessus, mais lorsque vous insérez un enregistrement, le pilote MongoDB a généré un ObjectId unique pour vous permettre d'identifier ce document. Chaque document de la collection MongoDB a une _idvaleur unique. Vous pouvez fournir une valeur vous-même si vous en avez une qui est garantie d'être unique, ou MongoDB en générera une pour vous, comme il l'a fait dans ce cas. En règle générale, vous devez définir explicitement la valeur pour vous-même.

La méthode find_one est utile pour récupérer un seul document d'une collection, mais vous devrez souvent rechercher plusieurs enregistrements. Dans ce cas, vous aurez besoin de la méthode find , qui prend les mêmes options que cet appel, mais renvoie un fichier Result<Cursor>. Ceux Cursor- ci sont utilisés pour parcourir la liste des données renvoyées.

Les opérations de recherche et les documents de filtrage qui les accompagnent sont très puissants et vous les utiliserez probablement beaucoup. Si vous avez besoin de plus de flexibilité findet que vous find_onepouvez provisionner, je vous recommande de jeter un œil à la documentation du pipeline d'agrégation super puissant et, à mon avis, c'est l'une des fonctionnalités les plus puissantes de MongoDB. J'écrirai un autre article de blog dans cette série sur ce sujet - je l'attends avec impatience !

Mettre à jour les documents de la collection

Lorsqu'un document est stocké dans une collection, il peut être mis à jour de différentes manières. Si vous souhaitez remplacer complètement un document par un autre, vous pouvez utiliser la méthode find_one_and_replace , mais la mise à jour d'une ou plusieurs parties d'un document est plus courante à l'aide de update_one ou update_many . Chaque mise à jour de document individuel est atomique, ce qui peut être une fonctionnalité utile pour maintenir la cohérence de vos données dans un document. N'oubliez pas update_manyqu'il ne s'agit pas d'une opération atomique en soi - pour cela, vous devrez utiliser une transaction ACID multi-documents, disponible dans MongoDB depuis la version 4.0 (et disponible pour les collections segmentées depuis 4.2). La version 1.0 du pilote Rust ne prend pas encore en charge les transactions, mais elle le sera bientôt.

Pour mettre à jour un document dans MongoDB, vous avez besoin de deux documents BSON : Le premier document décrit la requête pour trouver le document que vous souhaitez mettre à jour ; Le deuxième document décrit les opérations de mise à jour que vous souhaitez effectuer sur le document de la collection. Bien que la date de "sortie" de Parasite soit en 2020, je pense que cela fait référence à la sortie aux États-Unis. L' année de sortie correcte est 2019, voici donc le code pour mettre à jour les enregistrements en conséquence :

// Update the document:
let update_result = movies.update_one(
   doc! {
      "_id": &insert_result.inserted_id,
   },
   doc! {
      "$set": { "year": 2019 }
   },
   None,
).await?;
println!("Updated {} document", update_result.modified_count);

Lorsque vous exécutez ce qui précède, il imprimera "Mise à jour 1 document". Si ce n'est pas le cas, quelque chose est arrivé au document vidéo que vous avez inséré précédemment. Peut-être que tu l'as supprimé ? Juste pour vérifier si la mise à jour a correctement mis à jour la valeur de l'année, voici une find_onecommande que vous pouvez ajouter à votre programme pour voir à quoi ressemble le document mis à jour :

// Look up the document again to confirm it's been updated:
let movie = movies
   .find_one(
      doc! {
            "_id": &insert_result.inserted_id,
      },
      None,
   ).await?
   .expect("Missing 'Parasite' document.");
println!("Updated Movie: {}", &movie);

Lorsque j'exécute ces blocs de code, le résultat ressemble au texte ci-dessous. Voyons comment cela montre que cette année est 2019 au lieu de 2020.

Updated 1 document
Updated Movie: { _id: ObjectId("5e835f3000415b720028b0ad"), title: "Parasite", year: 2019, plot: "A poor family, the Kims, con their way into becoming the servants of a rich family, the Parks. But their easy life gets complicated when their deception is threatened with exposure.", released: Date("2020-02-07 00:00:00 UTC") }

Supprimer un document de la collection

Dans les sections ci-dessus, vous avez appris à créer, lire et mettre à jour des documents dans une collection. Si vous avez exécuté votre programme plusieurs fois, vous avez certainement intégré pas mal de matériel pour le film Parasite ! C'est maintenant le bon moment pour supprimer cela en utilisant delete_manycette méthode. Le pilote de rouille MongoDB fournit 3 méthodes pour supprimer des documents :

find_one_and_delete supprimera un document de la collection et renverra le document supprimé, s'il existe.

delete_one trouvera les documents qui correspondent au filtre fourni et supprimera le premier document trouvé (le cas échéant).

delete_many, comme vous pouvez vous y attendre, trouvera les documents qui correspondent à un filtre fourni et les supprimera tous .

Dans le code ci-dessous, j'ai utilisé delete_manyparce que vous avez peut-être créé des enregistrements lors du test du code ci-dessus. Le filtre recherche uniquement les films par nom, il recherchera et supprimera tous les documents insérés, tandis que si vous recherchez par _idvaleur, il ne supprimera qu'un seul film, car l'identifiant est unique.

Si vous filtrez ou triez constamment sur un champ, vous devriez envisager d'ajouter un index à ce champ pour améliorer les performances à mesure que votre collection grandit. Consultez le Guide de l'utilisateur de MongoDB pour plus de détails.

// Delete all documents for movies called "Parasite":
let delete_result = movies.delete_many(
   doc! {
      "title": "Parasite"
   },
   None,
).await?;
println!("Deleted {} documents", delete_result.deleted_count);

Tu l'as fait! Les opérations de création, de lecture, de mise à jour et de suppression sont des opérations principales que vous utiliserez encore et encore pour accéder aux données de votre cluster MongoDB et les gérer. Après le goût que ce guide a à offrir, vous devriez certainement en savoir plus sur ce qui suit :

  • Le document de requête est utilisé pour toutes les opérations de lecture, de mise à jour et de suppression.
  • Le compartiment et la documentation MongoDB décrivent toutes les opérations fournies par le pilote MongoDB pour accéder à vos données et les modifier.
  • Le compartiment bson et les documents qui l' accompagnent décrivent comment créer et mapper des données à insérer ou à récupérer à partir de MongoDB.
  • Serde crate fournit un cadre pour le mappage entre les types de données Rust et BSON avec bson crate, il est donc important d'apprendre à en tirer parti.

Utiliser serdepour mapper les données à la structure

L'une des caractéristiques du bac bson qui n'est peut-être pas évidente est qu'il fournit le format de données BSON pour la serdetrame. Cela signifie que vous pouvez utiliser le serde bucket pour mapper entre les types de données Rust et BSON afin de maintenir la persistance dans MongoDB.

Pour un exemple de la façon dont cela est utile, voir l'exemple suivant sur la façon d'accéder au titlechamp d' new_movieun document ( sans le serde):

// Working with Document can be verbose:
if let Ok(title) = new_doc.get_str("title") {
   println!("title: {}", title);
} else {
   println!("no title found");
}

La première ligne du code ci-dessus récupère la valeur de titlepuis essaie de la récupérer sous forme de chaîne ( Bson::as_strrenvoie Nonesi la valeur est d'un autre type). Il y a pas mal de gestion des erreurs et de conversion. Le framework serde offre la possibilité de définir une structure comme celle ci-dessous, avec des champs qui correspondent au document que vous souhaitez recevoir.

// You use `serde` to create structs which can serialize & deserialize between BSON:
#[derive(Serialize, Deserialize, Debug)]
struct Movie {
   #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
   id: Option<bson::oid::ObjectId>,
   title: String,
   year: i32,
}

Notez l'utilisation Serializeet la Deserializemacro indique au serde que cette structure peut être sérialisée et décodée. L' serdeattribut est également utilisé pour indiquer au serde que idle champ struct doit être sérialisé en BSON en tant que _id, ce que MongoDB s'attend à ce qu'il soit appelé. Le paramètre skip_serializing_if = "Option::is_none"indique également au serde que si la valeur facultative de idest, Noneelle ne doit pas du tout être sérialisée. (Si vous fournissez _id: NoneBSON pour MongoDB, il stockera le document avec un identifiant de NULL, tandis que si vous ne le faites pas, un identifiant sera généré pour vous, ce qui est généralement le comportement que vous souhaitez.)

Le code ci-dessous crée une version Moviestructurée pour le film Captain Marvel. (N'est-ce pas un bon film ? J'adore ce film !) Après avoir créé la structure, avant de pouvoir l'enregistrer dans votre collection, elle doit être convertie en document BSON . Cela se fait en deux étapes : il est d'abord converti en une valeur Bson avec bson::to_bson, qui renvoie une Bsoninstance ; il est ensuite spécifiquement converti en a Documenten l'appelant as_document. Il est sûr d'appeler unwrapcela car je sais déjà que la sérialisation d'une structure en BSON produira un type de document BSON.

Une fois que votre programme a acquis une instance de bson Document, vous pouvez l'appeler insert_oneavec exactement de la même manière que vous l'avez fait dans la section ci-dessus intitulée Créer un document .

// Initialize struct to be inserted:
let captain_marvel = Movie {
   id: None,
   title: "Captain Marvel".to_owned(),
   year: 2019,
};

// Convert `captain_marvel` to a Bson instance:
let serialized_movie = bson::to_bson(&captain_marvel)?;
let document = serialized_movie.as_document().unwrap();

// Insert into the collection and extract the inserted_id value:
let insert_result = movies.insert_one(document.to_owned(), None).await?;
let captain_marvel_id = insert_result
   .inserted_id
   .as_object_id()
   .expect("Retrieved _id should have been of type ObjectId");
println!("Captain Marvel document ID: {:?}", captain_marvel_id);

Lorsque j'exécute le code ci-dessus, la sortie ressemble à ceci :

Captain Marvel document ID: ObjectId(5e835f30007760020028b0ae)

C'est formidable de pouvoir générer des données à l'aide des types de données natifs de Rust, mais je pense que pouvoir décoder les données dans une structure est encore plus précieux. C'est ce que je vais vous montrer ensuite. À bien des égards, c'est le même processus que ci-dessus, mais à l'envers.

Le code ci-dessous récupère un document vidéo, le convertit en une Bson::Documentvaleur, puis l'appelle from_bson, ce qui l'encode depuis BSON vers le type qui se trouve à gauche de l'expression. C'est pourquoi j'ai dû spécifier cela loaded_moviecomme type Moviesur le côté gauche, au lieu de simplement laisser le compilateur de rouille obtenir ces informations pour moi. Une alternative consiste à utiliser la notation turbofish dans from_bsonl'appel, en appelant explicitement from_bson::<Movie>(loaded_movie). En fin de compte, comme dans beaucoup de choses Rust, c'est votre choix.

// Retrieve Captain Marvel from the database, into a Movie struct:
// Read the document from the movies collection:
let loaded_movie = movies
   .find_one(Some(doc! { "_id":  captain_marvel_id.clone() }), None)
   .await?
   .expect("Document not found");

// Deserialize the document into a Movie instance
let loaded_movie_struct: Movie = bson::from_bson(Bson::Document(loaded_movie))?;
println!("Movie loaded from collection: {:?}", loaded_movie_struct);

Et au final, voici ce que j'obtiens lorsque j'imprime la présentation de débogage de la structure Movie (c'est pourquoi j'ai Debugbasé la définition de la structure ci-dessus) :

Movie loaded from collection: Movie { id: Some(ObjectId(5e835f30007760020028b0ae)), title: "Captain Marvel", year: 2019 }

Vous pouvez voir l'intégralité des exemples de code Tokio sur github .

Quand tu ne veux pas courir sous Tokio

Async-std

Si vous préférez utiliser async-stdau lieu de tokio, vous avez de la chance ! Les changements sont minimes. Vous devez d'abord désactiver les fonctionnalités par défaut et les activerasync-std-runtime :

[dependencies]
mongodb = { version = "1.0.0", default-features = false, features=["async-std-runtime"] }

Les seules modifications que vous devez apporter à votre code rouillé sont d'ajouter use async_std;les entrées et de baliser votre fonction principale asynchrone avec #[async_std::main]. Tout le reste de votre code doit être identique à l'exemple de Tokio.

use async_std;

#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {
   // Your code goes here.
}

Vous pouvez voir des exemples de code async-std complet sur github .

Code de synchronisation

Si vous ne souhaitez pas exécuter dans un framework asynchrone, vous pouvez activer la synchronisation. Dans votre Cargo.tomlfichier, désactivez les fonctionnalités par défaut et activez sync:

[dependencies]
mongodb = { version = "1.0.0", default-features = false, features=["sync"] }

Vous n'aurez plus besoin que votre fonction wrapper en soit une async fn. Vous aurez besoin d'utiliser une autre Clientinterface, définie dans mongodb::synccelle-ci, et vous n'avez pas besoin d'attendre les résultats des fonctions d'E/S :

// Use mongodb::sync::Client, instead of mongodb::Client:
let client = mongodb::sync::Client::with_uri_str(client_uri.as_ref())?;

// .insert_one().await? becomes .insert_one()?
let insert_result = movies.insert_one(new_doc.clone(), None)?;

Vous pouvez voir des exemples de synchronisation complète de code sur github .

Traduit de : https://www.mongodb.com/ 

What is GEEK

Buddha Community

Query of MongoDB | MongoDB Command | MongoDB | Asp.Net Core Mvc

https://youtu.be/FwUobnB5pv8

#mongodb tutorial #mongodb tutorial for beginners #mongodb database #mongodb with c# #mongodb with asp.net core #mongodb

Install MongoDB Database | MongoDB | Asp.Net Core Mvc

#MongoDB
#Aspdotnetexplorer

https://youtu.be/cnwNWzcw3NM

#mongodb #mongodb database #mongodb with c# #mongodb with asp.net core #mongodb tutorial for beginners #mongodb tutorial

Serde Rust: Serialization Framework for Rust

Serde

*Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.*

You may be looking for:

Serde in action

Click to show Cargo.toml. Run this code in the playground.

[dependencies]

# The core APIs, including the Serialize and Deserialize traits. Always
# required when using Serde. The "derive" feature is only required when
# using #[derive(Serialize, Deserialize)] to make Serde work with structs
# and enums defined in your crate.
serde = { version = "1.0", features = ["derive"] }

# Each data format lives in its own crate; the sample code below uses JSON
# but you may be using a different one.
serde_json = "1.0"

 

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let point = Point { x: 1, y: 2 };

    // Convert the Point to a JSON string.
    let serialized = serde_json::to_string(&point).unwrap();

    // Prints serialized = {"x":1,"y":2}
    println!("serialized = {}", serialized);

    // Convert the JSON string back to a Point.
    let deserialized: Point = serde_json::from_str(&serialized).unwrap();

    // Prints deserialized = Point { x: 1, y: 2 }
    println!("deserialized = {:?}", deserialized);
}

Getting help

Serde is one of the most widely used Rust libraries so any place that Rustaceans congregate will be able to help you out. For chat, consider trying the #rust-questions or #rust-beginners channels of the unofficial community Discord (invite: https://discord.gg/rust-lang-community), the #rust-usage or #beginners channels of the official Rust Project Discord (invite: https://discord.gg/rust-lang), or the #general stream in Zulip. For asynchronous, consider the [rust] tag on StackOverflow, the /r/rust subreddit which has a pinned weekly easy questions post, or the Rust Discourse forum. It's acceptable to file a support issue in this repo but they tend not to get as many eyes as any of the above and may get closed without a response after some time.

Download Details:
Author: serde-rs
Source Code: https://github.com/serde-rs/serde
License: View license

#rust  #rustlang 

Insert & Save method in MongoDB | Inserting Document | CRUD Operation in MongoDB

#MongoDB
#AspDotNetExplorer
https://youtu.be/CohnNdE_rjM

#mongodb #mongodb tutorial for beginners #mongodb tutorial #mongodb database #learn mongodb

Execute MongoDB Command | Create, Drop and Select Database | MongoDB | Asp.Net Core Mvc

https://youtu.be/SKpNG83X2Ig

#mongodb #mongodb with asp.net core #mongodb with c# #mongodb tutorial for beginners #mongodb tutorial #learn mognodb