Chapitre 2 MongoDB - Partie 1
Chapitre 2 MongoDB - Partie 1
Chapitre 2 MongoDB - Partie 1
Bases de données
avancées & Big Data
Dr FERRAHI ibtisam
Maitre de conférence B, USTHB
2
MongoDB
JSON
3
22/04/2020
1
15/10/2024
JSON
4
22/04/2020
JSON
{
" Nom_série " : " La casa de papel ",
"Acteur " : [" María Pedraza ","Miguel Herrán","Jaime Lorente"]
Tableau
5
22/04/2020
JSON
▰ Une valeur peut être une chaîne de caractères, un nombre, true ou false ou
null, un objet, un tableau :
6
22/04/2020
2
15/10/2024
Introduction
▰ Table = Collection
▰ En BDR, tous les tuples d’une table ont les mêmes champs (mais les valeurs peuvent être
différentes (les valeurs sont affectées à des colonnes)
▰ Dans une collection MongoDB, les documents peuvent ne pas avoir un champ partage (pas
de colonnes dans un document MongoDB).
3
15/10/2024
Document MongoDB
▰ Le champ _id
▻ Seul champ obligatoire, utilisé comme une clé primaire dans une collection
▻ Peut être de tout type autre que tableau
▰ Deux façons des relations entre les données: Références et données imbriquées
▰ Références
▻ Inclusion des liens ou références d’un document à un autre
▻ C’est à l’application de résoudre ces références pour accéder aux données associées
▻ On utilise un modèle de données normalisé Contact document
{
_id: <ObjectId2>
User document
user_id: <ObjectId1>
{ phone: ‘’123-456-789’’
_id: <ObjectId1> email: ‘’[email protected]’’
}
username: ‘’ Mohamed’’ ,
} Access document
{
_id: <ObjectId3>
user_id: <ObjectId1>
level: ‘’M2’’
group: ‘ASD’’
}
4
15/10/2024
Opération de Lecture
▰ Lecture
▻ Cible une unique collection spécifique de documents
▻ Cible un critère ou des conditions spécifiques, pour identifier le document à retourner
▻ Peut inclure une projection sur les champs du document à retourner
▻ Peut définir des modificateurs pour imposer des limites, un ordre, un filtre
5
15/10/2024
▰ Projection
▻ Deuxième argument de la méthode find()
▻ Peuvent spécifier la liste des champs à afficher ou à exclure
▻ Mise à part pour exclure le champs _id ( qui est affiché par défaut) il est interdit
de mixer les projections inclusives et exclusives
Exemple:
Collections restriction projection
▰ Modification
▻ Création, mise à jour ou suppression de données
▻ Ces opérations modifient les données d’une seule collection
▻ Définition de critère pour sélectionner les document à modifier ou à supprimer
▰ Exemple:
db.users. insert (
{
name: ‘’brahim’’,
age: 26,
stutus: ‘’Dr’’
}
)
6
15/10/2024
▰ Insertion de document
▻ Si vous voulez ajouter un document sans champ _id, le système l’ajoute lui–même en
générant un champ de type ObjectId
▰ Suppression de documents
▻ La méthode remove supprime des documents d’une collection
▻ Accepte des critères de sélection des documents à supprimer
▻ Supprime par défaut tous les documents correspondant aux critères de sélection (
sauf indication du contraire dans un flag approprié)
▰ Exemple:
7
15/10/2024
MongoDB: Commandes
23
Installation
24
8
15/10/2024
Instalation
25
26
Collection , BD
27
9
15/10/2024
Commandes de base
▰ Show dbs
▻ Permet d’afficher les BDs existantes
▰ Use employes
▻ Permet de baculer de la Bd test vers la BD nomée db_employes
▰ Show collection
▻ Permet d’afficher les collections existantes
28
Insérer un document
29
Insérer un document
30
10
15/10/2024
Recherche
▰ db.employes.find()
31
Affichage structuré
32
33
11
15/10/2024
db.employes.update(
{"_id":ObjectId("6372c9a52f91adb32fb04e1e")},
{ nom : "Ali",
date_recrutement : 2011,
service : "commercial",
salaire : 54000}
);
34
35
Suppression
▰ On peut supprimer :
▻ Certains éléments d’une collection
▻ Tous les éléments d’une collection
▻ La collection entière (ses éléments et elle‐même)
36
12
15/10/2024
Suppression
37
Suppression
38
39
13
15/10/2024
Supprimer une BD
40
Renommer une BD
>db.copyDatabase("db_to_rename","db_renamed","localhost")
> use db_to_rename
> db.dropDatabase();
41
>db.copyDatabase("db_to_rename","db_renamed","localhost")
> use db_to_rename
> db.dropDatabase();
42
14
15/10/2024
Renommer une BD
>db.collection.renameCollection( newCollectionName)
43
Requête find()
▰ Commande ‘’db.collectionName.find({…},{…})’’
▻ Le premier argument est la condition de sélection/filtrage :
Seuls les enregistrements satisfaisant cette condition seront retenus
▻ Le second argument (optionnel) décrit la projection : L’information voulue de chaque en
registrement retenu après filtrage
▰ Exemples :
▻ db.employes.find({date_recrutement : 2000}) :
▻ Tous les employés de la collection Employés ayant été recruté en 2000
▻ Equivalent à : SELECT* FROM Employés WHERE (date_recretement = 2000)
45
15
15/10/2024
Requête find()
▰ Commande ‘’db.collectionName.find({…},{…})’’
▻ Le premier argument est la condition de sélection/filtrage :
Seuls les enregistrements satisfaisant cette condition seront retenus
▻ Le second argument (optionnel) décrit la projection : L’information voulue de chaque en
registrement retenu après filtrage
▰ Exemples :
▻ db.employes.find({date : 2000},{nom : 1, _id : 0}) :
▻ Tous les employés de la collection Employés ayant été recruté en 2000
▻ Affiche le nom (uniquement) des employés retenus
▻ Equivalent à : SELECT nom FROM employés WHERE (date_recretement = 2000)
46
Opérateur(s) AND
▰ Cas 1: L’opérateur AND est implicite à condition de porter sur les attribues différents
▻ Préciser plusieurs valeurs d’attributs dans le premier argument constitue un « AND »
▻ db.employes.find({poste: ‘ing’’, date_rect : 2011},{nom : 1, _id : 0})
▻ db.Employes.find({$and : [ { poste : "Ing"},
{ date_rect :: 2000},
{ nom : 1, _id : 0}) ]
▻ Tous les employés de la collection Employes dont le poste occupé est ingénieur ET
l’année de recrutement est 2011
▻ Equivalent à :
▻ SELECT nom 48
FROM employé
16
15/10/2024
Opérateur(s) AND
49
Opérateur(s) AND
▻ Tous les employés de la collection Employés dont le poste est ingénieur et la date de
recrutement est comprise entre 2000 (inclus) et 2010 (exclus)
50
Opérateur OR
51
17
15/10/2024
Opérateur OR
52
53
54
18
15/10/2024
▰ $regex est un opérateur de comparaison qui permet d'effectuer des recherches de motifs dans les
champs de texte.
▰ $regex { fieldName : { $regex : regExp, $options: options }}
▻ { regionName : { $regex : /^lor/ , $options : ‘i’ } }
▻ /^lor/ : commence par ‘’lor’’
▻ $options : ‘i’ insensible à la casse
▻ si le nom de la région commence par lor ou Lor ou LoR ou LOR alors
retourne true
▰ $text est utilisé pour effectuer des recherches textuelles dans une collection. Il permet de rechercher
des documents qui contiennent un certain texte dans les champs indexés en texte.
▻ Créer un index ‘’text’’ sur le champs à analyser
db.collection.createIndex(‘’champsA’’ : ‘’text’’)
▻ Lancer un filtrage sur le contenu de ce champ (et sur d’autres )
▻ db.collection.find({‘’champsB’ : ‘’valeurA’’,
$text : {$search : ‘’valeurB’’})
▻ ’champsB doit valoir ‘’valeurA’’ ET ‘’ ’champsA’’ doit doit contenir ‘valeurB’’
56
57
19
15/10/2024
▰ Exemple
{ "_id": 1, "title": "Introduction to MongoDB", "content": "MongoDB is a NoSQL database..." }
{ "_id": 2, "title": "Querying in MongoDB", "content": "Learn how to query data in MongoDB..." }
{ "_id": 3, "title": "Indexing in MongoDB", "content": "MongoDB supports various types of indexing..." }
db.collection.find({ $text: {
$search: "MongoDB",
$language: "english",
$caseSensitive: false,
$diacriticSensitive: false } });
59
Opérateurs d’évaluation
▰ Quand les opérateurs natifs de MongoDB ne suffisent plus, on peut introdire du code JavaScript
▰ Attention: c’est plus lent.
▰ $where { fieldName
{ fieldName :{ :{
$where : JavaScript
$where expression
: JavaScript expression
}
}
}
}
▻ fieldName: C'est le nom du champ sur lequel vous souhaitez appliquer la condition définie par
l'expression JavaScript.
▻ $where: C'est l'opérateur qui indique que vous allez utiliser une expression JavaScript pour
effectuer la condition.
▻ JavaScript_expression: C'est l'expression JavaScript qui sera évaluée pour chaque document. Elle
doit retourner une valeur booléenne, true ou false, pour déterminer si le document satisfait la
condition.
60
20
15/10/2024
Opérateurs d’évaluation
▻ Quand les opérateurs natifs de MongoDB ne suffisent plus, on peut introdire du code
JavaScript
▻ Attention: c’est plus lent.
▰ Deux syntaxes possibles : récupérer des documents dans la collection Ventes où la différence
entre les valeurs du "credits" et "debits" est inférieure à zéro.
▻ db.Collection .find({ $where: “this.credits ‐ this.debits <0})
▻ db.Collection.find({ $where: function()
{ return obj.credits ‐ obj.debits <0;}
}) 61
db.collectionName.find { fieldName : {
$where : JavaScript expression
}
}
▰ db.students.find ({ "grades":
{ $where: "this.grades.reduce((acc, val) => acc + val, 0) / this.grades.length > 85" }
});
Le reduce permet de calculer la moyenne des notes et vérifie si elle est supérieure à 85.
62
db.collectionName.find { fieldName : {
$where : JavaScript expression
}
}
63
21
15/10/2024
▰ $all: Un opérateur qui indique que tous les éléments spécifiés dans le tableau doivent être
présents dans le champ tableau pour qu'un document soit retourné
▰ Syntaxe : { arrayFieldName : {
$all : [val1, val2, val3…]
}
}
64
▰ Syntaxe : { arrayFieldName : {
$all : [val1, val2, val3…]
}
}
▰ Exemple 1 : Rechercher les documents où le champ "cours" contient tous les éléments spécifiés
dans le tableau [ "BDNoSQL", "SI" ]
▻ db.modules.find ({cours : { $all : [‘BDNoSQL’’, ‘SI’’] } } )
▰ Exemple 2 : Recherche de documents où le champ "tags" contient tous les éléments spécifiés
▻ db.products.find({ tags: { $all: ["electronics", "gadgets", "smartphones"] } })
65
{ "_id": 1,
"name": "Aline",
"cours": ["BDNoSQL", "BDD", "SI"]
},
{ "_id": 2, db.students.find({ cours: { $all: ["BDNoSQL", "SI"] } })
"name": " Nesrine",
"cours": ["BDD", "SI", "Algorithmes"]
},
{ "_id": 3,
"name": "Ahmed", { "_id": 1,
"cours": ["BDNoSQL", "Web Development", "SI"] "name": "Aline",
} "cours": ["BDNoSQL", "BDD", "SI"]
},
{ "_id": 3,
"name": "Ahmed",
"cours": ["BDNoSQL", "Web Development", "SI"]
}
66
22
15/10/2024
67
68
23
15/10/2024
[ { "_id": 1,
"name": "Aline",
"grades": [ { "subject": "Mathématiques", "score": 92 },
{ "subject": "Physique", "score": 88 },
{ "subject": "Chimie", "score": 95 } ] },
{ "_id": 2, db.students.find({ "grades": { $size: 2 } })
"name": "Nesrine",
"grades": [ { "subject": "Mathématiques", "score": 88 },
{ "subject": "Physique", "score": 90 },
{ "subject": "Chimie", "score": 94 } ] },
{ "_id": 3,
{"name": "Ahmed",
"name": "Ahmed",
"grades": [ { "subject": "Mathématiques", "score": 94 },
"grades": [ { "subject": "Mathématiques", "score": 94 },
{ "subject": "Chimie", "score": 89 }
{ "subject": "Chimie", "score": 89 }
]
]
}]
}]
70
▰ Syntaxe générale :
▻ db.laCollection.find(…).methode(…)
▻ Ou bien: db.laCollection.methode(…)
▻ La méthode peut être:
▻ Sort()
▻ Count()
▻ forEach()
72
24
15/10/2024
73
75
25
15/10/2024
Agrégations
d’opérations avec
aggregate (…)
76
▰ Principe :
▻ Aggregate est une fonctionnalité puissante de MongoDB utilisée pour traiter et
transformer des ensembles de données.
▻ Elle permet d'effectuer des opérations complexes comme des regroupements, des
filtrages, des tris, et des transformations en pipeline.
▻ Pipeline de données : Un ensemble d'étapes où chaque étape applique une
transformation aux données et transmet le résultat à la suivante.
77
▰ Syntaxe:
▻ db.collectionName.aggregate({op1}, {op2}, {op3}…)
▻ La sortie d’une opération est l’entrée de la suivante, ou bien la sortie finale de
l’agrégation
▻ On peut pipeliner successivement autant d’opérations que l’on veut
▻ Plus lent que des commandes natives, car les données pipelinées
ne profitent pas des index !
26
15/10/2024
79
[
{ "client": "FRIHI Mohamed", "produit": "Livre", "quantité": 2 },
{"client": "FRIHI Mohamed", "produit": "Stylo", "quantité": 5 }
] 80
27
15/10/2024
▰ $match :
▻ $match est un opérateur de pipeline dans MongoDB qui filtre les documents en
fonction de certaines conditions, de manière similaire à l'opérateur find().
▻ Il est souvent utilisé dans le cadre d'une requête aggregate() pour sélectionner
uniquement les documents pertinents à un stade précoce du pipeline.
▰ $match :
▻ Exemple 1: On ne s’intéresse qu’aux employés dont la date de recrutement est >2011
▻ db.Employes.aggregate( [{"$match" : {"date_recrutement" : {$gt : "2011"}}}] )
▻ Equivalent à : SELECT *
FROM employes
WHERE date_recrutement > '2011’;
83
28
15/10/2024
▰ $match :
▻ Exemple 4: les produits les plus vendus à partir de 2022
▻ db.ventes.aggregate([ { $match: { date: { $gte: ISODate('2022-01-01') } } },
{ $group: { _id: "$produit", ventesTotales: { $sum: "$quantité" } } },
{ $sort: { ventesTotales: -1 } }, { $limit: 5 } ]);
▰ $project :dans le framework d'agrégation de MongoDB est utilisée pour remodeler les
documents dans le pipeline d'agrégation.
▻ L'opérateur $project est utilisé dans le pipeline d'aggregation pour inclure, exclure ou
ajouter des champs dans les documents résultants.
▻ Il permet de transformer les documents en ne conservant que les informations
nécessaires pour l'analyse.
▻ Cette phase vous permet d'inclure, exclure ou transformer des champs dans les
documents résultants
▻ Permet de projeter des attributs : seulement ceux voulus, et au
besoin en les renommant ou en créant de nouveaux attributs
87
29
15/10/2024
▰ $project :
▻ Exemple : On ne retient que les employés dont l’année de recrutement est >2007
▻ db.Employes.aggregate( {"$match" : {"date_recrutement" : {$gt : "2007"}}},
{"$project" : {"nom" : 1, "date_recrutement" : 1}} )
▻ Ce filtre inclut uniquement les champs nom et date_recrutement dans les résultats.
88
▰ Exemple 2:
{ "_id": 1, "produit": "A", "quantite": 10, "date": ISODate("2022-01-05") }
{ "_id": 2, "produit": "B", "quantite": 15, "date": ISODate("2022-01-10") }
{ "_id": 3, "produit": "A", "quantite": 20, "date": ISODate("2022-01-15") }
db.ventes.aggregate([
{ $match: { date: { $gte: ISODate('2022-01-01') } } },
{ $group: { _id: "$produit", ventesTotales: { $sum: "$quantite" } } },
{ $project: { _id: 0, produit: "$_id", ventesTotales: 1, date: "$_id" } },
{ $sort: { ventesTotales: -1 } },
{ $limit: 5 } ]);
▰ $group :
Permet de regrouper les enregistrements retenus selon l’_id (que l’on peut redéfinir au passage)
, et d’appliquer des fonctions de groupe au autres attributs projetés
▻ Exemple : les fonctions deviennent l’_id, et on calcule la date de
recrutement, et leur nombre de recrutement
db.Employes.aggregate( [ { "$match" : {" date_recrutement " : {$gt : "2007"}}},
{ "$project" : {" fonction" : 1, " date_recrutement " : 1}},
{ "$group" : { _id : "$fonction",
"debut" : {$min : "$ date_recrutement"},
"occurences" : {$sum : 1}
}
} ])
90
30
15/10/2024
▰ $sort :
Permet d’ordonner les enregistrements selon un des attributs, par ordre croissant
(+1) ou décroissant (‐1).
▰ Exemple : on ordonne les employés par ordre décroissant de l’année de
rectrutement
db.Employes.aggregate(
{"$match" : {" date_rectutement" : {$gt : "2007"}}},
{"$project" : {" fonction" : 1, " date_rectutement" : 1}},
{"$group" : {_id : "$fonction",
"debut" : {$min : "$date_recrutement"},
"occurences" : {$sum : 1}}},
{"$sort" : {"occurences" : ‐1}} ) 91
92
▰ $unwind :
Permet de remplacer un enregistrement contenant un tableau par une suite
d’enregistrements contenant chacun un seul élément du tableau
▰ Exemple : { "_id" : 1, "item" : "ABC", "sizes": [ "S", "M", "L"] }
db.theCollection.aggregate( [ { $unwind: "$sizes" } ] ) ou bien:
db. theCollection.aggregate( [ { $unwind: { path: "$sizes" } } ] )
→ { "_id" : 1, "item" : "ABC", "sizes" : "S" }
{ "_id" : 1, "item" : "ABC", "sizes" : "M" }
{ "_id" : 1, "item" : "ABC", "sizes" : "L" }
Important! : en cas de tableau vide [], ou de champ null, ou inexistant,
l’enregistrement initial disparait de la sortie du $unwind (!)
93
31
15/10/2024
▰ $unwind
▻ Permet de remplacer un enregistrement contenant un tableau par une suite
d'enregistrement contenant chacun un seul élément du tableau
▻ Si on veut conserver les enregistrements des tableaux vides →
on utilise une spécification de $unwind
Exemple : { "_id" : 1, "item" : "EFG", "sizes": [ ] }
db.theCollection.aggregate( [
{ $unwind: { path: "$sizes", preserveNullAndEmptyArrays: true} } ] )
→ { "_id" : 2, "item" : "EFG" }
94
Exercice 2
▰
{
Soit la collection des employés suivante:
"id": 111,
"prenom": "Jean",
"nom": "Martin",
"date_naissance": "15/04/1985",
"salaire": 3800.45,
"poste": "Développeur",
"departements": [
{
"nom": "Développement logiciel",
"lieu": "Paris",
"duree_travail": "3 ans"
},
{
"nom": "Qualité logicielle",
"lieu": "Lyon",
"duree_travail": "2 ans"
}
] 95
}
32