Académique Documents
Professionnel Documents
Culture Documents
TP MongoDB
Configuration de la VM nosql2022 (si vous l’utilisez) :
- OS : Ubuntu 64 bits
- 2 cœurs de processeurs (ou plus).
- RAM : 4 Go (ou plus)
- Augmenter la taille de la mémoire vidéo au maximum + activer l’accélération 3D
- Login (root) : nosql ; mot de passe : nosql
- Activer le presse-papier partagé (bidirectionnel)
- Si l’affichage de la VM est en faible résolution, installer les Additions Invité (drivers) : Menu
Périphériques puis Insérer l’image CD des Additions Invité… L’image d’un CD va alors être chargée
et les drivers installés. Redémarrer si nécessaire la machine virtuelle et changer la résolution de
l’affichage.
1. Configuration et lancement
Démarrage du serveur
Lancer un Terminal et démarrer le serveur MongoDB :
cd mongodb/bin
./mongod --dbpath /home/nosql/mongodb/data/db
Remarques :
• Le dossier contenant les BD NoSQL est : /data/db. Il est nécessaire de le créer au préalable.
Il est possible, comme nous l’avons fait, de définir un chemin de localisation des données en
utilisant l’option --dbpath de l’exécutable mongod.
• Si les fichiers de MongoDB ne sont pas considérés comme des exécutables, dans le home de
l’utilisateur nosql, exécuter la commande suivante :
chmod -R 777 mongodb
Cette commande démarre le processus principal de la base de données. Vous devez obtenir l’écran
suivant (attente de connexions) :
Comme on peut le voir, le daemon mongod fonctionne par défaut sur l’hôte localhost et le port 27017.
Ne pas fermer cette fenêtre.
Connexion à MongoDB
Le shell mongo.sh (situé dans mongodb/bin) permet de se connecter au daemon mongod. Exécuter le shell
dans une nouvelle fenêtre Terminal (./mongo).
Vincent COUTURIER 1
Vous devez obtenir le prompt > permettant de saisir les commandes MongoDB.
Remarques :
• La commande mongo sert à manipuler MongoDB. C’est un shell s’appuyant sur un moteur javascript, et
va donc permettre d’utiliser toutes les fonctions standard du javascript en plus des commandes de
base de données qui n’utilisent pas la syntaxe javascript (use, show, etc.).
• Pour se connecter à une base distante et/ou un port différent, on ajoutera les paramètres –port et –
host à la suite de la commande mongo
A la place du shell, il est possible d’utiliser Robo3T (anciennement robomongo). Lancer robo3t à partir de
la logithèque Ubuntu :
L’exécutable se trouve également dans Ordinateur > snap > robo3t-snap > 4 > bin.
Vincent COUTURIER 2
La connexion au server local est configurée par défaut. Cliquer sur « Test », puis sur « Save ».
Remarque : vous pouvez aussi utiliser MongoDB Compass, le client « officiel », installé dans la VM, mais
privilégiez la console plutôt que le query builder car il vous sera demandé l’écriture de requêtes en DS.
Query builder pour la recherche de documents :
Vincent COUTURIER 3
Query builder pour insérer un document (NE PAS L’UTILISER) :
Console :
Vincent COUTURIER 4
2. Utilisation de MongoDB
Options sur la connexion : créer une nouvelle base de données ; version du SGBD, etc.
Remarque : dans le shell, on peut exécuter les commandes suivantes (inutiles dans le client graphique) :
• db : pour connaître la base courante
• db.version() : pour connaître la version du serveur MongoDB. Dans l’outil graphique :
Vincent COUTURIER 5
• show dbs : pour connaitre les bases gérées pas le server mongod sur lequel on est connecté
(seules les bases non vides, i.e. contenant des collections sont affichées).
• use NomDeLaBase : pour choisir une base. Si la base de données n’existe pas, celle-ci sera créée
au moment de l’insertion de données ou à la création manuelle d’une collection vide de documents
dans celle-ci.
Ouvrir le shell qui vous permettra par la suite d’exécuter les commandes.
Nous allons manipuler des documents BSON. BSON permet de gérer des types de données divers : byte,
int32, int64, double, ObjectID, Timestamp, Date, tableaux, etc. (http://bsonspec.org).
Quand on insère des données (sous forme de document) dans une collection inexistante, MongoDB crée la
collection implicitement. De même si la base de données n’existe pas.
Dans la base de données bdetudiants (use bdetudiants), ajouter les documents suivants à la collection.
Vincent COUTURIER 6
db.etudiants.findOne() // Retourne un seul étudiant. Sensible à la casse !
Dans Robo3T :
Vincent COUTURIER 7
Remarques :
• Vous pouvez utiliser l’aide de façon suivante pour afficher les informations sur les commandes :
help, db.help(),db.<collection>.help(), db.<collection>.find().help(), etc.
• En saisissant les commandes sans parenthèses, vous pouvez également voir le code des
commandes :
Remarque : le fichier JSON précédent montre comment on peut modéliser une application simplement. On
s’affranchit d’utiliser une collection pour les adresses par exemple. On parle de dématérialisation ou
d’imbrication de documents (le champ adresse contient un document de 4 champs). Ici, elle a un sens car
Vincent COUTURIER 8
les données (adresses) sont distinctes et elle permet d’accéder rapidement aux données. Elle n’en a pas
toujours quand on retrouve fréquemment les mêmes données (par exemple, même informations sur le
diplôme, etc.). Se pose alors la question de la redondance et surtout de la modification (écritures
multiples nécessaires).
var etudiant = {
"_id" : 2,
"nom" : "DURAND",
"prenoms" : ['Marc'],
"date naissance" : ISODate("1985-06-10T00:00:00Z"),
"adresse" : {
"numero" : "12",
"rue" : "17 Avenue de la Concorde",
"ville" : "Dijon",
"cp" : "21000" }
}
db.etudiants.insertOne(etudiant)
db.etudiants.find()
// identique à db["etudiants"].find() ou db.getCollection("etudiants").find() ou
db.etudiants.find({})
Créer un 4ème étudiant (sans la colonne _id). Vérifier que la colonne _id a bien été ajoutée (un ObjectId
a été généré).
db.etudiants.insertOne({
"nom" : "EVENOT",
"prenoms" : ['Vincent','Paul'],
"adresse" : {
"numero" : "12",
Vincent COUTURIER 9
"rue" : "Arc en Ciel",
"ville" : "Annecy",
"cp" : "74000"
},
"notes" : [3.0,5.0,8.0,18.0,19.0],
"annee experience" : 3
})
Ajouter d’autres étudiants (au minimum 3 de plus). Vous pourrez utiliser http://generatedata.com
pour compléter votre jeu de données.
2.2. Requêtes
Essayer également les requêtes précédentes dans le shell MongoDB (Terminal) pour voir les
différences d’affichage. Il sera nécessaire de charger la base des étudiants : use bdetudiants.
Ecrire des requêtes permettant de montrer l’utilisation des opérateurs précédents. Vous devrez
ajouter des données.
Exemples de requêtes :
A. find()
1. Afficher le nom des étudiants habitant à …
2. Afficher les étudiants habitant à … (sans l’ID)
3. Afficher les étudiants habitant à … ou à …
4. Afficher les étudiants habitant à … ou à … ordonné par … décroissant
5. Afficher les étudiants dont le … est parmi … (utiliser $in)
6. Afficher les étudiants dont le … est … et le … est …
7. Afficher tous les étudiants n’habitant pas à …
8. Afficher les étudiants n’habitant ni à …, ni à …
9. Afficher les étudiants dont l'un des prénoms n'est ni … ni …
10. Afficher les étudiants qui habitent à … mais pas dans la rue …
11. Afficher les étudiants ayant plus de … ans d’expérience
12. Afficher les étudiants dont … est présent
13. Afficher les étudiants dont l’un des prénoms commence par …
Vincent COUTURIER 10
14. Afficher les étudiants à partir du numéro 2 (utiliser skip ou $skip)
15. Trier les étudiants par … décroissant
16. Afficher le nombre moyen d’années d’expérience des étudiants
17. Afficher le nombre moyen d’années d’expérience par … (par ex. par ville).
18. Afficher le nombre moyen d’années d’expérience par … et par … (par ex. par ville et par CP).
19. Afficher le nombre d’étudiants habitant à …
20. Afficher le nombre d’étudiants dont le champ … est présent
21. Afficher le nombre d’étudiants ayant un nom différent
22. Afficher par ordre décroissant, pour chaque prénom existant, le nombre d'étudiants qui portent
ce prénom (vous pourrez utiliser $unwind)
Etc.
Remarque : Pour dupliquer une collection dans Compass, créer d’abord la 2nde collection, puis :
db.collection1.aggregate([{ $match: {} }, { $out: "collection2" }])
Vincent COUTURIER 11
Créer la collection formations (dans la même base de données).
Collection etudiants qui contient l’objet (ou une partie de l’objet) formations :
Avantages Inconvénients
Pas besoin de jointure => rapide en lecture Si un intitulé de formation change, il faut modifier
tous les étudiants ayant cet intitulé (par exemple
DUT -> BUT) => peu rapide en MaJ
Volume de données plus important
Ajouter un champ formation, contenant l’ID et l’intitulé, aux étudiants. Vous pourrez utiliser la
commande db.collection.updateOne (ou updateMany) pour mettre à jour un seul / plusieurs
enregistrements) ou db.collection.findAndModify ou db.collection.findOneAndUpdate.
Indications :
- Vous n’êtes pas sensé connaitre l’ID auto-généré de la formation. Une première requête doit
récupérer une formation donnée (_id et intitule).
var formation=db.formations.find(…).toArray();
…
Pour voir le contenu d’une variable, il suffit de faire :
var formation=db.formations.find(…).toArray();
formation
- Une 2nde requête met à jour les étudiants en fonction de la formation récupérée. Vous pourrez
créer un code « dynamique » de la façon suivante :
var etudiants = db.etudiants.find(…).toArray();
for (var index = 0; index < etudiants.length; index++) {
switch (index%4) {
case 0: db.etudiants.updateOne(…)
break;
…
Vincent COUTURIER 12
}
}
- Afin de répondre à la question 2.5, au moins 2 étudiants devront suivre la formation « DUT
Informatique ».
Ecrire une requête affichant les étudiants (nom, prénoms) et leur formation.
Avantages Inconvénients
Rapide en MaJ (si, par exemple, changement Peu rapide en lecture car nécessite une jointure
d’intitulé de la formation)
Volume de données plus réduit
Ajouter un champ formation, contenant uniquement l’ID, aux étudiants. Mêmes indications que
pour la section précédente.
ATTENTION, on doit obtenir ceci :
{
…
"formation" : ObjectId("60832a82ec1f4c2be651f239")
}
Et non :
{
…
"formation" : {
"_id" : ObjectId("60832a82ec1f4c2be651f239")
}
}
Ecrire une requête permettant de réaliser une « jointure » entre les 2 collections de 2
manières :
• En partant d’etudiants2
• En partant de formations
Vous n’afficherez que les nom, prénoms et formation pour chaque étudiant. Vous pourrez utiliser
les commandes $lookup, $replaceRoot et $project :
https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
Dans la clause $project, vous mettrez tous les champs que vous souhaitez cacher à 0 (ou false).
Exemple de résultat que vous devez obtenir :
{
intitule: 'DUT Informatique',
nom: 'DURAND',
prenoms: [
'Alain',
'Paul'
]
}
…
{
Vincent COUTURIER 13
intitule: 'Informatique et CyberSécurité',
nom: 'EVENOT',
prenoms: [
'Vincent',
'Paul'
]
}
2.5. Transactions
Transactions MongoDB :
• https://dzone.com/articles/mongodb-transactions-your-very-first-transaction-w
• https://docs.mongodb.com/manual/core/transactions/
Vincent COUTURIER 14
Executer rs.initiate()
Vincent COUTURIER 15
3. Outils d’administration
• Sauvegarde :
o Lancer la commande mongodump : ./mongodump
Plus de détails sur la commande :
https://docs.mongodb.com/database-tools/mongodump/
o La base de données a été sauvegardée.
• Restauration :
o Exemple : restauration des données dans une nouvelle base nommée bdetudiants2
4. JSON schema
Un schéma permet d’ajouter des contraintes sur les champs (contraintes de types de données, de valeurs
possibles, etc.).
Vincent COUTURIER 16
Ouvrir le fichier movies_references_exporte.json et regarder son contenu. Ce fichier Json contient des
films.
Créer des documents Json ne respectant pas le schéma et qui généreront des erreurs :
Indexation :
• https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/
• https://docs.mongodb.com/manual/reference/method/db.collection.getIndexes/
• https://docs.mongodb.com/manual/reference/method/db.collection.totalIndexSize/
• https://docs.mongodb.com/manual/reference/method/db.collection.reIndex/
Explain : https://docs.mongodb.com/manual/reference/method/db.collection.explain/
Validation (à utiliser avant et après la création d’index pour pouvoir comparer) :
https://docs.mongodb.com/manual/reference/method/db.collection.validate/
Statistiques : https://docs.mongodb.com/manual/reference/method/db.collection.stats/
A vous de tester et d’expliquer sur la collection des films (car il y a plus de données) :
Comme les SGBD relationnels, les index MongoDB sont basés sur des B-Tree. Principaux types d’index (A
expliquer, vous pourrez ajouter du code testant ces index) :
• Les index primaires :
Vincent COUTURIER 17
• Les index simples :
• Unique :
• Partiel :
• Epars (Sparse) :
• Insensibilité́ à la casse :
Les index doivent pouvoir tenir en RAM dans un cluster MongoDB, afin d'avoir des performances optimales
: https://docs.mongodb.com/manual/tutorial/ensure-indexes-fit-ram/
6. Interface REST
Vincent COUTURIER 18
Dans le cas des films, la recherche se fera sur le titre.
Remarque : ici, nous n’avons affiché que les nom, prénoms et adresse de chaque étudiant.
Dans le cas des films, vous n’afficherez que les titre, genre et rôles.
Vincent COUTURIER 19