Concevoir un schéma de commande MongoDB

MongoDBBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez à concevoir un schéma MongoDB pour une application de commerce électronique. L'objectif est de créer un document unique et complet pour chaque commande, facile à gérer et à interroger. Vous commencerez par créer une structure de commande de base, puis vous l'enrichirez progressivement en intégrant des informations détaillées sur le client, une liste des articles commandés, les détails de paiement et un historique des statuts. Cette approche démontre la puissance du modèle de document de MongoDB pour les applications du monde réel.

Créer un document de commande de base

Dans cette première étape, vous allez vous connecter à MongoDB et créer une nouvelle base de données. Ensuite, vous insérerez votre premier document de commande, qui servira de fondation au schéma que nous allons construire dans les étapes suivantes.

Tout d'abord, ouvrez le MongoDB Shell. Cette interface interactive en ligne de commande vous permet de communiquer avec votre base de données MongoDB.

mongosh

Une fois dans le shell, vous verrez une invite >. Maintenant, basculez vers une nouvelle base de données nommée ecommerce. Si la base de données n'existe pas, MongoDB la créera pour vous lorsque vous stockerez des données pour la première fois.

use ecommerce

Ensuite, vous allez créer une collection nommée orders en y insérant un document. Ce document représentera une seule commande et contiendra des informations essentielles telles qu'un identifiant de commande, les détails du client, la date de la commande et son statut actuel.

Exécutez la commande suivante pour insérer le document :

db.orders.insertOne({
  order_id: "ORD001",
  order_date: new Date("2023-10-26T10:00:00Z"),
  customer_id: "CUST123",
  status: "pending",
  total: 150.0
});

Cette commande effectue les actions suivantes :

  • db.orders : Spécifie la collection orders dans la base de données actuelle.
  • insertOne() : Une méthode MongoDB pour insérer un seul document.
  • Le document lui-même est un objet de type JSON avec des paires clé-valeur pour order_id, order_date, customer_id, status et total.

Après une insertion réussie, MongoDB renverra un accusé de réception ainsi que l'_id unique du document nouvellement créé.

{
  "acknowledged": true,
  "insertedId": ObjectId("...")
}

Vous avez maintenant créé la structure de base d'une commande. Dans la prochaine étape, vous enrichirez ce document avec des informations plus détaillées.

Améliorer avec les détails du client intégrés

Un simple customer_id n'est souvent pas suffisant. Dans une application réelle, vous auriez fréquemment besoin du nom et de l'adresse du client lors de la récupération d'une commande. Au lieu d'effectuer une requête séparée vers une collection customers, nous pouvons intégrer ces informations directement dans le document de commande. C'est un modèle courant et puissant dans MongoDB qui améliore les performances de lecture.

Dans cette étape, vous allez mettre à jour le document de commande pour inclure des informations client détaillées et imbriquées. Si vous avez quitté le shell mongosh à l'étape précédente, veuillez le redémarrer et exécuter use ecommerce.

Utilisez la méthode updateOne() pour trouver le document avec order_id: "ORD001" et le modifier. L'opérateur $set remplace la valeur d'un champ par la valeur spécifiée, et $unset supprime complètement un champ.

db.orders.updateOne(
  { order_id: "ORD001" },
  {
    $set: {
      customer: {
        customer_id: "CUST123",
        first_name: "John",
        last_name: "Doe",
        email: "john.doe@example.com",
        shipping_address: {
          street: "123 Main St",
          city: "Anytown",
          state: "CA",
          zip_code: "12345"
        }
      }
    },
    $unset: {
      customer_id: ""
    }
  }
);

Dans cette commande :

  • Le premier argument { order_id: "ORD001" } est le filtre pour sélectionner le document à mettre à jour.
  • Le second argument contient les opérateurs de mise à jour :
    • $set : Nous définissons un nouveau champ customer qui est un document imbriqué contenant des informations détaillées.
    • $unset : Nous supprimons l'ancien champ customer_id de niveau supérieur pour éviter la redondance des données.

Pour vérifier vos modifications, vous pouvez récupérer le document mis à jour en utilisant findOne() :

db.orders.findOne({ order_id: "ORD001" });

La sortie affichera maintenant le document customer imbriqué, et le champ customer_id de niveau supérieur aura disparu. Cette structure intégrée maintient les données connexes ensemble dans un seul document.

Ajouter un tableau d'articles de commande

Une commande se compose généralement d'un ou plusieurs produits. La meilleure façon de modéliser cette relation un-à-plusieurs au sein d'un seul document de commande est d'utiliser un tableau de documents imbriqués. Chaque élément du tableau représentera un article de la commande.

Mettons à jour notre document de commande pour inclure une liste d'articles. Nous allons ajouter un champ items, qui sera un tableau. Chaque objet du tableau contiendra des détails sur un produit, tels que son ID, son nom, son prix et sa quantité.

Exécutez la commande updateOne suivante :

db.orders.updateOne(
  { order_id: "ORD001" },
  {
    $set: {
      items: [
        {
          product_id: "PROD01",
          name: "Laptop",
          price: 1200.0,
          quantity: 1
        },
        {
          product_id: "PROD02",
          name: "Mouse",
          price: 25.0,
          quantity: 1
        }
      ],
      total: 1225.0
    }
  }
);

Ici, nous utilisons à nouveau $set pour ajouter le tableau items. Nous mettons également à jour le champ total pour qu'il corresponde à la somme des prix des articles. Stocker le total calculé directement dans le document est une autre optimisation des performances, car cela évite le besoin d'agrégation à chaque lecture.

Vérifions à nouveau le document pour voir le nouveau tableau items.

db.orders.findOne({ order_id: "ORD001" });

Vous verrez le tableau items imbriqué dans le document de commande. Cette conception vous permet de récupérer une commande complète, y compris tous ses articles, avec une seule requête de base de données.

Intégrer les informations de paiement

Les détails de paiement sont une autre partie essentielle d'une commande. Similaire aux informations client et aux articles, les données de paiement peuvent être intégrées directement dans le document de commande. Cela inclut la méthode de paiement, l'identifiant de transaction et le statut.

Dans cette étape, vous ajouterez un sous-document payment à la commande.

db.orders.updateOne(
  { order_id: "ORD001" },
  {
    $set: {
      payment: {
        method: "credit_card",
        transaction_id: "TXN54321",
        status: "completed"
      }
    }
  }
);

Cette commande ajoute un objet payment avec trois champs : method, transaction_id et status. L'intégration de ces informations garantit que toutes les données relatives à une seule transaction sont situées au même endroit.

Visualisons maintenant la structure de notre document de commande.

db.orders.findOne({ order_id: "ORD001" });

Le document contient désormais des informations complètes sur la commande, le client, les articles et le paiement, toutes accessibles via une seule opération de lecture.

Suivre l'historique du statut de la commande

Une commande progresse à travers différentes étapes, telles que "en attente" (pending), "en cours de traitement" (processing), "expédiée" (shipped) et "livrée" (delivered). Bien que le champ de niveau supérieur status indique l'état actuel, il est souvent utile de conserver un journal de toutes les modifications de statut. Vous pouvez y parvenir en ajoutant un tableau status_history.

Dans cette dernière étape, vous mettrez à jour le statut de la commande à "en cours de traitement" (processing) et commencerez à construire le tableau status_history. L'opérateur $push est utilisé pour ajouter une valeur à un tableau.

Tout d'abord, ajoutons le statut initial "en attente" (pending) à l'historique et mettons à jour le statut actuel à "en cours de traitement" (processing).

db.orders.updateOne(
  { order_id: "ORD001" },
  {
    $set: { status: "processing" },
    $push: {
      status_history: {
        status: "pending",
        timestamp: new Date("2023-10-26T10:00:00Z")
      }
    }
  }
);

Maintenant, ajoutons le nouveau statut "en cours de traitement" (processing) à l'historique pour que le journal soit complet.

db.orders.updateOne(
  { order_id: "ORD001" },
  {
    $push: {
      status_history: {
        status: "processing",
        timestamp: new Date("2023-10-26T11:30:00Z")
      }
    }
  }
);

Cette approche fournit une piste d'audit complète du cycle de vie de la commande. Vous pouvez interroger le document pour voir son historique complet à tout moment.

db.orders.findOne({ order_id: "ORD001" });

Le document inclut désormais un tableau status_history, vous offrant une vue complète du parcours de la commande. Pour quitter le shell MongoDB, tapez exit et appuyez sur Entrée.

Résumé

Dans ce laboratoire, vous avez appris à concevoir un schéma MongoDB pratique et efficace pour une commande de commerce électronique. Vous avez commencé avec un document de base et l'avez progressivement enrichi en intégrant des données connexes. Vous avez réussi à créer un document unique contenant les détails du client, un tableau d'articles de commande, des informations de paiement et un historique complet des statuts. Ce modèle de document intégré est un concept fondamental dans la conception de schémas MongoDB qui permet de créer des applications performantes et évolutives en réduisant le besoin de jointures complexes et de requêtes multiples.