Gérer les documents imbriqués MongoDB

MongoDBBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez à gérer efficacement les documents embarqués dans MongoDB. Les documents embarqués, ou documents imbriqués, sont une fonctionnalité fondamentale du modèle de données de MongoDB qui vous permet de stocker des données complexes et hiérarchiques au sein d'un seul document. Vous apprendrez une série de techniques, notamment la création de documents avec des données imbriquées, la mise à jour de champs spécifiques en leur sein, la suppression d'éléments et l'interrogation de ces structures complexes. Vous apprendrez également à imposer une structure de données cohérente à l'aide de la validation de schéma. Ces compétences sont essentielles pour construire des applications robustes et efficaces avec MongoDB.

Créer des documents avec des données imbriquées

Dans cette étape, vous apprendrez à créer des documents avec des structures imbriquées dans MongoDB. C'est une compétence fondamentale pour modéliser des données liées au sein d'un seul document.

Tout d'abord, ouvrez le shell MongoDB (mongosh) pour commencer à interagir avec la base de données. Toutes les commandes suivantes dans ce laboratoire seront exécutées dans ce shell, sauf indication contraire.

mongosh

Ensuite, basculez vers une nouvelle base de données nommée bookstore. Si cette base de données n'existe pas, MongoDB la créera pour vous lorsque vous y stockerez des données pour la première fois.

use bookstore

Maintenant, vous allez créer une collection nommée books et y insérer un seul document. Ce document contiendra des objets imbriqués et un tableau d'objets imbriqués, représentant les détails d'un livre.

db.books.insertOne({
    title: "Advanced MongoDB",
    author: {
        name: "Jane Smith",
        contact: {
            email: "jane.smith@example.com",
            phone: "+1-555-123-4567"
        }
    },
    published: {
        year: 2023,
        publisher: "Tech Publications"
    },
    chapters: [
        { number: 1, title: "Introduction to Nested Documents" },
        { number: 2, title: "Advanced Document Structures" }
    ]
})

Dans le document que vous venez de créer :

  • author et published sont des documents (objets) imbriqués.
  • Le document author contient un autre document imbriqué, contact.
  • chapters est un tableau qui contient plusieurs documents imbriqués, chacun représentant un chapitre.

Pour visualiser le document et confirmer sa structure, utilisez la méthode find().

db.books.find()

Vous devriez voir la sortie suivante, confirmant que le document a été correctement inséré. _id est un identifiant unique généré automatiquement par MongoDB.

[
  {
    _id: ObjectId("..."),
    title: 'Advanced MongoDB',
    author: {
      name: 'Jane Smith',
      contact: {
        email: 'jane.smith@example.com',
        phone: '+1-555-123-4567'
      }
    },
    published: {
      year: 2023,
      publisher: 'Tech Publications'
    },
    chapters: [
      { number: 1, title: 'Introduction to Nested Documents' },
      { number: 2, title: 'Advanced Document Structures' }
    ]
  }
]

Mettre à jour les champs imbriqués et les éléments de tableau

Après avoir créé des documents, vous devrez souvent modifier certaines parties. Dans cette étape, vous apprendrez à mettre à jour des champs spécifiques dans les documents et tableaux imbriqués. Vous devriez toujours être dans le shell mongosh de l'étape précédente.

Tout d'abord, mettons à jour les informations de contact de l'auteur. Pour ce faire, vous utilisez l'opérateur $set avec la notation par points pour spécifier le chemin exact du champ que vous souhaitez modifier. Cette commande modifiera le numéro de téléphone et ajoutera un nouveau champ website.

db.books.updateOne(
    { title: "Advanced MongoDB" },
    { $set: {
        "author.contact.phone": "+1-888-999-0000",
        "author.contact.website": "www.janesmith.com"
    } }
)

La notation par points "author.contact.phone" indique à MongoDB de naviguer dans l'objet author, puis dans l'objet contact, et de mettre à jour le champ phone.

Ensuite, vous ajouterez un nouveau chapitre au tableau chapters en utilisant l'opérateur $push.

db.books.updateOne(
    { title: "Advanced MongoDB" },
    { $push: {
        chapters: {
            number: 3,
            title: "MongoDB Advanced Techniques"
        }
    } }
)

Vous pouvez également mettre à jour un élément spécifique dans un tableau. Modifions le titre du premier chapitre. Nous utilisons l'opérateur positionnel $, qui agit comme un espace réservé pour le premier élément du tableau qui correspond à la condition de requête ("chapters.number": 1).

db.books.updateOne(
    { title: "Advanced MongoDB", "chapters.number": 1 },
    { $set: {
        "chapters.$.title": "Introduction to Nested Documents (Revised)"
    } }
)

Pour vérifier toutes les modifications, récupérez à nouveau le document. La méthode .pretty() formate la sortie pour la rendre plus lisible.

db.books.find({ title: "Advanced MongoDB" }).pretty()

La sortie affichera le numéro de téléphone mis à jour, le nouveau site web, le troisième chapitre ajouté et le titre révisé du premier chapitre.

Supprimer les champs imbriqués et les éléments de tableau

Dans cette étape, vous apprendrez à supprimer des parties de vos documents. Cela inclut la suppression de champs spécifiques, de documents imbriqués entiers et d'éléments d'un tableau.

Tout d'abord, supprimons le champ website des informations de contact de l'auteur en utilisant l'opérateur $unset. La valeur fournie à $unset (dans ce cas, une chaîne vide "") n'a pas d'importance ; l'opérateur supprime simplement le champ spécifié.

db.books.updateOne(
    { title: "Advanced MongoDB" },
    { $unset: { "author.contact.website": "" } }
)

Ensuite, vous supprimerez un élément d'un tableau. Supprimons le troisième chapitre (celui avec number: 3) du tableau chapters en utilisant l'opérateur $pull. L'opérateur $pull supprime tous les éléments du tableau qui correspondent à la condition spécifiée.

db.books.updateOne(
    { title: "Advanced MongoDB" },
    { $pull: {
        chapters: { number: 3 }
    } }
)

Enfin, vous pouvez supprimer un objet imbriqué entier. Supprimons l'objet contact du document author, en utilisant à nouveau l'opérateur $unset.

db.books.updateOne(
    { title: "Advanced MongoDB" },
    { $unset: { "author.contact": "" } }
)

Pour voir le résultat de ces opérations de suppression, interrogez à nouveau le document.

db.books.find({ title: "Advanced MongoDB" }).pretty()

La sortie montrera que le champ website et l'objet contact entier ont disparu, et que le tableau chapters ne contient plus que deux éléments.

Interroger des documents avec des données imbriquées

L'interrogation est une opération fondamentale de base de données. Dans cette étape, vous apprendrez à interroger des documents en fonction de valeurs dans des objets et tableaux imbriqués. Pour nous assurer d'avoir un ensemble de données propre pour ces exemples, supprimez d'abord la collection books existante.

db.books.drop()

Maintenant, insérez quelques nouveaux documents avec différentes structures imbriquées pour pratiquer l'interrogation.

db.books.insertMany([
    {
        title: "MongoDB Essentials",
        author: {
            name: "John Doe",
            experience: { years: 5, specialization: "Database Design" }
        },
        tags: ["beginner", "database", "nosql"],
        chapters: [
            { number: 1, title: "Introduction", pages: 25 },
            { number: 2, title: "Advanced Concepts", pages: 45 }
        ]
    },
    {
        title: "Advanced Database Techniques",
        author: {
            name: "Jane Smith",
            experience: { years: 8, specialization: "Distributed Systems" }
        },
        tags: ["advanced", "distributed", "nosql"],
        chapters: [
            { number: 1, title: "System Design", pages: 35 },
            { number: 2, title: "Performance Optimization", pages: 55 }
        ]
    }
])

Pour trouver un livre par un champ dans un document imbriqué, utilisez la notation par points. Cette requête trouve le livre écrit par "John Doe".

db.books.find({ "author.name": "John Doe" })

Vous pouvez aller plus loin dans les structures imbriquées. Cette requête trouve les livres dont la spécialisation de l'auteur est "Database Design".

db.books.find({ "author.experience.specialization": "Database Design" })

Pour trouver des documents où un tableau contient une valeur spécifique, vous pouvez interroger directement le champ du tableau. Ceci trouve tous les livres tagués "nosql".

db.books.find({ tags: "nosql" })

Vous pouvez également rechercher des documents où un élément de tableau répond à une certaine condition. Cette requête trouve les livres qui ont au moins un chapitre de plus de 40 pages, en utilisant l'opérateur $gt (supérieur à).

db.books.find({ "chapters.pages": { $gt: 40 } })

Enfin, vous pouvez combiner plusieurs conditions. Cette requête trouve les livres tagués comme "advanced" écrits par un auteur ayant 5 ans d'expérience ou plus ($gte signifie supérieur ou égal à).

db.books.find({
    "author.experience.years": { $gte: 5 },
    tags: "advanced"
})

Appliquer la structure des documents avec la validation de schéma

Pour maintenir la cohérence des données, MongoDB vous permet d'imposer une structure spécifique pour les documents d'une collection à l'aide de la validation de schéma JSON (JSON Schema). Dans cette étape, vous allez créer une nouvelle collection avec un validateur pour vous assurer que tous les documents respectent une structure prédéfinie.

Tout d'abord, créez une nouvelle collection nommée courses. Lors de sa création, vous passerez une option validator contenant les règles du schéma.

db.createCollection("courses", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: ["title", "instructor", "duration", "topics"],
         properties: {
            title: {
               bsonType: "string",
               description: "must be a string and is required"
            },
            instructor: {
               bsonType: "object",
               required: ["name", "email"],
               properties: {
                  name: { bsonType: "string" },
                  email: {
                     bsonType: "string",
                     pattern: "^.+@.+$"
                  }
               }
            },
            duration: {
               bsonType: "int",
               minimum: 1,
               maximum: 100
            },
            topics: {
               bsonType: "array",
               minItems: 1,
               items: { bsonType: "string" }
            }
         }
      }
   }
})

Ce schéma exige que chaque document possède un title, un instructor, une duration et des topics. Il définit également le type de données pour chaque champ, y compris des règles imbriquées pour l'objet instructor et le tableau topics.

Maintenant, essayez d'insérer un document qui respecte ces règles. Cette opération devrait réussir.

db.courses.insertOne({
   title: "MongoDB Advanced Techniques",
   instructor: {
      name: "Jane Smith",
      email: "jane.smith@example.com"
   },
   duration: 40,
   topics: ["Nested Documents", "Schema Validation"]
})

Ensuite, tentez d'insérer un document qui viole les règles du schéma. Ce document a un type de données incorrect pour instructor.name, un format d'email invalide, une duration en dehors de la plage autorisée et un tableau topics vide.

db.courses.insertOne({
   title: "Invalid Course",
   instructor: {
      name: 123,
      email: "invalid-email"
   },
   duration: 200,
   topics: []
})

Cette insertion échouera, et MongoDB renverra une erreur Document failed validation (Document échoué à la validation). Cela empêche la sauvegarde de données incohérentes et contribue à maintenir l'intégrité de votre base de données.

Résumé

Dans ce laboratoire, vous avez appris les techniques fondamentales pour gérer les documents imbriqués dans MongoDB. Vous avez commencé par créer des documents avec des structures imbriquées complexes, y compris des objets et des tableaux. Vous avez ensuite pratiqué la mise à jour de champs spécifiques à l'aide de la notation par points et d'opérateurs tels que $set et $push. Vous avez également appris à supprimer des données avec $unset et $pull. De plus, vous avez exploré comment effectuer des requêtes ciblées sur des données imbriquées et, enfin, comment imposer l'intégrité des données en définissant et en appliquant un validateur JSON Schema à une collection. Ces compétences sont cruciales pour construire des applications qui exploitent efficacement le modèle de document flexible de MongoDB.