Introduction
Dans ce laboratoire, vous apprendrez à utiliser les références MongoDB pour modéliser les relations entre les données. Vous construirez un système simple de gestion de bibliothèque avec les collections authors et books. Grâce à des étapes pratiques, vous apprendrez à créer des documents, à les lier à l'aide de références, à interroger des données connexes entre les collections, à mettre à jour ces références et à améliorer les performances des requêtes avec des index. Ce laboratoire fournit une base pratique pour la modélisation des données dans MongoDB.
Créer des collections et des documents de référence
Dans cette étape, vous allez configurer votre base de données et créer deux collections : authors et books. Vous apprendrez le concept fondamental de la référence de documents en liant un livre à son auteur.
Tout d'abord, ouvrez le MongoDB Shell. Ce shell interactif est l'endroit où vous exécuterez toutes vos commandes de base de données.
mongosh
Une fois dans le shell, vous verrez une invite test>. Basculez vers une nouvelle base de données nommée library_db. Si la base de données n'existe pas, MongoDB la créera lorsque vous stockerez des données pour la première fois.
use library_db
Maintenant, créez votre premier auteur. Insérez un document dans la collection authors. Nous spécifions un _id personnalisé pour cet auteur afin de faciliter sa référence ultérieurement.
db.authors.insertOne({
_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
name: "Jane Austen",
nationality: "British",
birthYear: 1775
})
Ensuite, insérez un document dans la collection books. Le champ author_id contient l'ObjectId de l'auteur que vous venez de créer. C'est ainsi que vous créez une référence.
db.books.insertOne({
title: "Pride and Prejudice",
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1813,
genre: "Classic Literature"
})
Vous avez maintenant créé une relation un-à-un. Pour vérifier cela, vous pouvez récupérer les documents que vous venez de créer.
Tout d'abord, trouvez l'auteur :
db.authors.findOne({ name: "Jane Austen" })
Exemple de sortie :
{
_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
name: 'Jane Austen',
nationality: 'British',
birthYear: 1775
}
Maintenant, trouvez le livre et observez le champ author_id, qui fait référence à l'auteur.
db.books.findOne({ title: "Pride and Prejudice" })
Exemple de sortie :
{
_id: ObjectId("..."),
title: 'Pride and Prejudice',
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1813,
genre: 'Classic Literature'
}
Vous pouvez rester dans le shell mongosh pour les étapes suivantes.
Lier plusieurs documents
Un auteur écrit généralement plus d'un livre. Dans cette étape, vous apprendrez à lier plusieurs documents "enfants" (livres) à un seul document "parent" (auteur). Cela démontre une relation un-à-plusieurs.
Continuez à travailler dans le shell mongosh. Ajoutons deux autres livres de Jane Austen. Utilisez la commande insertMany pour insérer plusieurs documents à la fois. Les deux nouveaux livres référenceront le même author_id.
db.books.insertMany([
{
title: "Sense and Sensibility",
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1811,
genre: "Classic Literature"
},
{
title: "Emma",
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1815,
genre: "Classic Literature"
}
])
Maintenant que Jane Austen a trois livres dans notre base de données, récupérez-les tous en utilisant la méthode find() et en filtrant par author_id.
db.books.find({ author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1") })
Exemple de sortie :
[
{
_id: ObjectId("..."),
title: 'Pride and Prejudice',
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1813,
genre: 'Classic Literature'
},
{
_id: ObjectId("..."),
title: 'Sense and Sensibility',
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1811,
genre: 'Classic Literature'
},
{
_id: ObjectId("..."),
title: 'Emma',
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1815,
genre: 'Classic Literature'
}
]
Vous pouvez également compter rapidement combien de livres sont associés à un auteur spécifique en utilisant countDocuments.
db.books.countDocuments({ author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1") })
Exemple de sortie :
3
Cette simple requête confirme efficacement le nombre de documents liés.
Interroger plusieurs collections avec $lookup
Jusqu'à présent, vous avez récupéré des livres en utilisant un author_id connu. Une approche plus puissante consiste à combiner les données des deux collections en une seule requête. Dans cette étape, vous utiliserez l'étape d'agrégation $lookup pour effectuer une jointure externe gauche (left outer join) de la collection books vers la collection authors.
Tout d'abord, ajoutons un autre auteur et un livre pour rendre notre requête plus intéressante.
db.authors.insertOne({
_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2"),
name: "Charles Dickens",
nationality: "British",
birthYear: 1812
})
db.books.insertOne({
title: "Oliver Twist",
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2"),
published: 1837,
genre: "Historical Fiction"
})
Maintenant, construisons un pipeline d'agrégation. Cette requête commencera par la collection books et "cherchera" l'auteur correspondant pour chaque livre.
db.books.aggregate([
{
$lookup: {
from: "authors",
localField: "author_id",
foreignField: "_id",
as: "author_details"
}
}
])
L'étape $lookup possède les champs suivants :
from: "authors": Spécifie la collection avec laquelle effectuer la jointure.localField: "author_id": Le champ des documents d'entrée (provenant debooks).foreignField: "_id": Le champ des documents de la collection "from" (provenant deauthors).as: "author_details": Le nom du nouveau champ tableau qui est ajouté aux documents d'entrée.
Exemple de sortie (pour un document) :
{
_id: ObjectId("..."),
title: 'Pride and Prejudice',
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
published: 1813,
genre: 'Classic Literature',
author_details: [
{
_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b1"),
name: 'Jane Austen',
nationality: 'British',
birthYear: 1775
}
]
}
Comme vous pouvez le constater, les informations de l'auteur sont maintenant intégrées dans chaque document de livre sous le champ author_details. Cela vous permet d'interroger simultanément des champs provenant des deux collections.
Mettre à jour et maintenir les références
Les données ne sont pas toujours statiques. Vous pourriez avoir besoin de corriger des erreurs ou de supprimer des données, ce qui nécessite de mettre à jour ou de supprimer des documents et leurs références. Dans cette étape, vous apprendrez à mettre à jour une référence et à gérer les documents "orphelins".
Imaginez que vous découvriez que le livre "Emma" a été attribué par erreur à Jane Austen et qu'il devrait être assigné à Charles Dickens. Vous pouvez corriger cela en utilisant la commande updateOne avec l'opérateur $set.
db.books.updateOne(
{ title: "Emma" },
{ $set: { author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2") } }
)
Vérifiez le changement en retrouvant le livre et en consultant son author_id.
db.books.findOne({ title: "Emma" })
Exemple de sortie :
{
_id: ObjectId("..."),
title: 'Emma',
author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2"),
published: 1815,
genre: 'Classic Literature'
}
Maintenant, explorons ce qui se passe lorsqu'un document parent est supprimé. Si nous supprimons un auteur, tous les livres qui référencent cet auteur deviennent "orphelins". Supprimons Charles Dickens de notre base de données.
db.authors.deleteOne({ name: "Charles Dickens" })
Le document de l'auteur a disparu, mais les livres "Emma" et "Oliver Twist" ont toujours un author_id qui pointe vers l'auteur supprimé. Cela peut entraîner des problèmes d'intégrité des données. Dans une application réelle, vous implémenteriez une logique pour gérer cela, comme la suppression des livres orphelins ou leur réaffectation.
Pour ce laboratoire, nettoyons manuellement en supprimant les deux livres orphelins.
db.books.deleteMany({ author_id: ObjectId("6633c9a5b4e3e8a5c8a8f8b2") })
Cette commande supprime tous les documents de la collection books qui référencent l'auteur maintenant supprimé, garantissant ainsi la cohérence de nos données.
Améliorer les performances des requêtes avec des index
Lorsque vos collections grossissent, les requêtes qui filtrent sur un champ spécifique peuvent devenir lentes. En effet, MongoDB doit scanner chaque document pour trouver les correspondances. Pour optimiser cela, vous pouvez créer un index sur les champs que vous interrogez fréquemment. Dans notre cas, author_id dans la collection books est un candidat parfait.
Dans cette étape, vous allez créer un index sur le champ author_id pour accélérer les recherches des livres d'un auteur.
Utilisez la commande createIndex sur la collection books. L'argument { author_id: 1 } indique à MongoDB de créer un index ascendant sur le champ author_id.
db.books.createIndex({ author_id: 1 })
MongoDB traitera cela en arrière-plan. Une fois terminé, il renverra un message confirmant la création de l'index.
Exemple de sortie :
{
"numIndexesBefore": 1,
"numIndexesAfter": 2,
"createdCollectionAutomatically": false,
"ok": 1
}
Pour vérifier que l'index existe, vous pouvez utiliser la commande getIndexes. Celle-ci listera tous les index de la collection books.
db.books.getIndexes()
Vous devriez voir deux index : l'index par défaut sur _id et le nouvel index author_id_1 que vous venez de créer.
Exemple de sortie :
[
{ "v": 2, "key": { "_id": 1 }, "name": "_id_" },
{ "v": 2, "key": { "author_id": 1 }, "name": "author_id_1" }
]
Avec cet index en place, toute requête qui filtre ou trie par author_id, y compris l'étape $lookup que vous avez utilisée précédemment, sera significativement plus rapide sur de grands ensembles de données.
Enfin, vous pouvez quitter le shell MongoDB.
exit
Résumé
Dans ce laboratoire, vous avez appris les bases de l'utilisation des références de documents dans MongoDB. Vous avez commencé par créer des collections et lier des documents avec des références ObjectId. Vous avez ensuite pratiqué la gestion des relations un-à-plusieurs, l'interrogation entre collections à l'aide de la puissante étape d'agrégation $lookup, et le maintien de l'intégrité des données en mettant à jour et en nettoyant les références. Enfin, vous avez amélioré les performances des requêtes en créant un index sur un champ de référence. Ces compétences sont essentielles pour construire des applications évolutives et efficaces avec MongoDB.

