Chapitre 2 MongoDB - Partie 1

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 32

15/10/2024

Bases de données
avancées & Big Data

Dr FERRAHI ibtisam
Maitre de conférence B, USTHB

2
MongoDB

JSON

▰ JSON : JavaScript Object Notation.


▰ Format de données textuelles dérivé de la notation des objets du langage JavaScript.
▰ Simple et complet pour la présentation des objets
▰ Utilise des types de données connus et simples à décrire
▰ Bonne lisibilité de la syntaxe
▰ JSON est plus simple que XML, et il est très facile à associer à un langage de programmation.
▰ JSON est massivement utilisé dans les applications web (AJAX), les web-services (REST), et … les
bases de données NoSQL.

3
22/04/2020

1
15/10/2024

JSON

▰ Json se base sur deux structures


❑ Objet: c’est une collection de couple Nom/Valeur
❑ Tableau: c’est une liste de valeurs ordonnées
▰ Exemple: Couples nom/ valeur
objet

4
22/04/2020

JSON

▰ Json se base sur deux structures


❑ Objet: c’est une collection de couple Nom/Valeur
❑ Tableau: c’est une liste de valeurs ordonnées
▰ Exemple: Couple nom/ valeur

{
" Nom_série " : " La casa de papel ",
"Acteur " : [" María Pedraza ","Miguel Herrán","Jaime Lorente"]
Tableau

5
22/04/2020

JSON

▰ L’objet est un ensemble de couples Nom/ Valeur non ordonnée

▰ Un tableau est une collection de valeurs ordonnées :

▰ 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

▰ MongoDB (de Humongous, qui veut dire énorme)


▰ SGBD NoSQL orienté document à schéma flexible et distribuable
▰ Ecrit en C++
▰ Distribué sous licence AGPL
▰ Développé en 2007 par firme MongoDB

SQL Vs. MongoDB

▰ Table = Collection

▰ Enregistrement (tuple) = Document

▰ 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).

Structure de données MongoDB

▰ Données représentées dans un schéma flexible


▰ Données stockées sous forme de documents ( clé valeur) JSON
▰ La structure de données n’est pas fixée à sa création
▻ Mais en générale les documents d’une même collection ont une structure similaire
(homogénéité)
▰ Les documents sont organisées sous forme de collections
▻ Groupe de documents reliées par des indexes en commun
{ Nom : ‘’ Ali’’ ,
Age : 25
Section : ‘’ A ‘’
Modules : [ ‘’ Bases de données ‘’, ‘’ Entrepôt de données ‘’ ]
{ Nom : ‘’ Mohamed’’ ,
} Age : 22
Section : ‘’ A ‘’
Modules : [ ‘’ Bases de données ‘’, ‘’ Mathématique‘’ ]
}

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

▰ Les champs indexés ont une taille limite (1 Mo)


▰ Les noms des champs ne peuvent pas commencer par un $, contenir le caractère
« , » ou le caractère « null »

Document MongoDB: Limites

▰ Taille max d’un document: 16Mo


▻ Utilisation de l’api Gridfs pour stocker des documents plus large que la taille autorisée
▻ Gridfs permet de diviser les documents en chunks de même taille et les stocker sous
forme de documents séparés
▰ MongoDB préserve l’ordre des champs du document comme défini a leur création sauf:
▻ Que le champ _id doit toujours figurer en premier
▻ Les opérations de update qui incluent le renommage d’un champs peut entrainer le
changement de l’ordre des champs dans le documents
▰ Champs _id
▻ Création d’un index unique à la création d’une collection
▻ Utilisation conseillée d’un Objectid: objet petit (12o ) unique et rapide à générer

Structure de documents MongoDB

▰ 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

Structure de documents MongoDB

▰ Données imbriquées (Embedded document)


▻ Sauvegarder les données associées dans la même structure de documents
▻ Il est possible d’inclurent des document dans un tableau ou un champ
▻ Permet aux application d’extraire et manipuler plusieurs niveaux de hiérarchies en une
seule instruction
▻ Ce sont des modèle de données dénormalisées
{ _id: <ObjectId1>
username: ‘’ Mohamed’’ ,
contact: { Embedded sub
phone: ‘’123-456-789’’
email: ‘’[email protected]’’ documents
}
access: {
level: ‘’M2’’ Embedded sub
group: ‘ASD’’
}
documents
}

Structure de documents MongoDB

Comment choisir entre Références et données imbriquées?


▰ On choisit les références quand:
▻ L’imbrication va produire des données dupliquées sans grand avantage en terme de
performance de lecture
▻ On veut représenter des relations many-to-many complexes
▻ On veut représenter de larges ensembles de données hiérarchiques
▰ On choisit les documents imbriquées quand:
▻ On a des relations contains entre les éléments ( modèle one-to-one)
▻ On a des relation one-to many ou les documents fils (many) apparaissent toujours
dans le contexte des documents parents (one)

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

Collection Query Criteria Modifier


db.users.find ( { age: { $gt : 18 } } ) . sort ( { age : 1 } )

5
15/10/2024

Opération de Lecture MongoDB

▰ MongoDB fournit une méthode db.collection.find() pour l’extraction de données


▻ Accepte les critères de la requête, ainsi que les projections
▻ Retourne un curseur vers les documents correspondants
▰ Fournit également une méthode db.collection.findOne() retournant un seul document

Opération de Lecture MongoDB

▰ 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

db . Users . find ( { age : 18 } , { name : 1, _id : 0 } )

Opération d’Ecriture MongoDB

▰ 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

Opération d’Ecriture MongoDB

▰ 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

db.users. insert ( Collection


{
name: ‘’brahim’’, Field: value
▻ age: 26, Field: value Document
stutus: ‘’Dr’’ Field: value
}
)

Opération d’Ecriture MongoDB

▰ Mise à jour de document


▻ Méthode update peut accepter des critère de sélection des documents à modifier, et
des options qui affectent son comportement
▻ Une opération update modifie un seul document par défaut ( plusieurs docs si
multi:true)
▻ Existence de l’option upsert: true et que le document à modifier n’existe pas dans la
même collection, il est automatiquement inséré
db.users. Update ( Collection
{ age : { $gt : 18} Update criteria
},
{ $set: { status : ‘’Dr’’ } }, Update action
{ multi :true} Update option
)

Opération d’Ecriture MongoDB

▰ 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:

db.users. remove ( Collection


{
stutus: ‘’D’’ Remove criteria
}
)

7
15/10/2024

Opération d’Ecriture MongoDB

▰ Les opérations d’écriture sont atomiques au niveau d’un document


▻ Aucune opération de lecture ne peut affecter atomiquement plus qu’un seul document
ou collection
▻ L’utilisation des données imbriquées facilite l’écriture
▻ La normalisation des données (référence vers données dans d’autres collections)
implique plusieurs opérations d’écriture qui ne sont pas atomique

▰ Certains modifications augmente la taille des documents


▻ Pour le moteur de stockage de MongoDB, si la taille d’un document dépasse la taille
autorisée pour ce document, MongoDB le réalloue sur le disque
▻ Si votre application nécessite plusieurs modification qui augmente la taille des
documents, considèrent plutôt l’utilisation des références

MongoDB: Commandes

23

Installation

▰ Crée un répertoire de stockage.

▰ Lance le serveur MongoDB le répertoire MongoDB\bin

24

8
15/10/2024

Instalation

▰ Lance un client MongoDB sur le répertoire c:\mongodb\bin

25

▰ Juste après la création de la BdD et la connexion d’un client :

26

Collection , BD

▰ Par défaut on référence la base « test »

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

▰ db.employes.insert ({nom : "mohamed", fonction : "comptable"})

29

Insérer un document

▰ db.employes.insert ({nom : "mohamed", fonction : "comptable"})

30

10
15/10/2024

Recherche

▰ db.employes.find()

31

Affichage structuré

▻ Ajouter ‘’.pretty()’’ permet de mieux afficher les données structurées

32

Mise a jours d’un enregistrement

▰ La mise à jours d’un enregistrement se fait par un UPDATE


▰ Attention! La mise a jour permet d’écraser tout l’enregistrement mais le _id restera le
même

33

11
15/10/2024

db.employes.update(
{"_id":ObjectId("6372c9a52f91adb32fb04e1e")},
{ nom : "Ali",
date_recrutement : 2011,
service : "commercial",
salaire : 54000}
);

34

Mise à jour et ajout de champs d’un enregistrement

▰ Modifier un champs / ajouter un champ à un enregistrement

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

▰ Supprimer un enregistrement données


▻ db.nom_collection.remove({nom : "Ali"}}

37

Suppression

▰ Supprimer le contenue de la collection


▻ db.nom_collection.remove({})

▻ La collection est vide mais elle existe encore

38

▰ Supprimer la collection définitivement db.nom_collection.drop()

39

13
15/10/2024

Supprimer une BD

▰ Supprimer une bases de données db.dropDatabase()


▻ Permet de supprimer la base de données en cours d’utilisation
▻ MongoDB continue à la référencée → il faut passer à une autre base

40

Renommer une BD

▰ Renommer une BD: pour renommer une base de Mongo il faut:


▻ La copier avec :
▻ db.copyDatabase(fromdb, todb, fromhost, username, password, mechanism)
▻ puis effacer la première version avec : db.dropDatabase()

>db.copyDatabase("db_to_rename","db_renamed","localhost")
> use db_to_rename
> db.dropDatabase();

41

Renommer une collection

▰ Renommer une BD: pour renommer une base de Mongo il faut:


▻ La copier avec :
▻ db.copyDatabase(fromdb, todb, fromhost, username, password, mechanism)
▻ puis effacer la première version avec : db.dropDatabase()

>db.copyDatabase("db_to_rename","db_renamed","localhost")
> use db_to_rename
> db.dropDatabase();

42

14
15/10/2024

Renommer une BD

▰ Renommer une collection

>db.collection.renameCollection( newCollectionName)

▻ Ne fonctionne pas sur les collections « sharded »


▻ Ne peut pas déplacer une collection d’une base à une autre

43

Accès à des attributs composites/structurés

▰ Soit la collection suivante: {entreprise : "InfoBI",


services : { direction : {etage : 5, effectifs : 6}
comptabilité : {etage : 5, effectif :4}
innovation : {etage : 4, effectif 12 }
….
},
adresse : "Alger",
}

>find({"entreprise" : "InfoBI"},{"adresse" : 1})


> find({entreprise : "InfoBI"},{adresse : 1})
> find ({"entreprise": "InfoBI"},{"services.innovation.etage" : 1}
> find ({entreprise : "InfoBI"},{services.innovation.etage : 1}

Les chemins sur plusieurs niveaux doivent être entre ‘’ ‘’ 44

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érateurs des requêtes

▰ Liste des divers types d’opérateurs


▰ Comparaisons : ▰ Op de test sur élément :
▻ $eq, $ne ==, != ▻ $exists Existence d’un champ ?
▻ $gt, $gte, $lt,$lte >, >=, <, <= ▻ $type Teste le type d’un champ
▻ $in, $nin Є, Є ▰ Op d’évaluation :
▰ Logiques : ▻ $mod Calcule et teste le résultat d’un modulo
▻ $and, $or AND, OR ▻ $regex Recherche d’expression régulière
▻ $not, $nor NOT, NOR ▻ $text Analyse d’un texte
▰ Op de test sur tableau : ▻ $where
▻ $all Test sur le contenu Test de sélectionne des enregistrements

▻ $elemMatch d’un tableau


▻ $size Taille du tableau 47

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

▰ Cas 2: Réaliser plusieurs tests numériques sur un même attribut


▻ Préciser plusieurs valeurs d’attributs dans le premier argument constitue un « AND »
▻ db.employes.find({poste : ‘’ing’’, date_rect : {$gte : 2000, $lt : 2010}}, {nom : 1, _id : 0})
▻ Tous les employés de la collection Employés dont le poste est ingénieur et la date de
recrutement est entre 2000 et 2010
▰ Si les deux tests numériques sur le même attribut ne sont pas regroupés→ MongoDB ne
retiendra que le résultat du dernier

49

Opérateur(s) AND

▰ Cas 3: utiliser l’opérateur AND


▻ Utiliser un opérateur $and explicite, mais il ne faut pas le mélanger avec une «,»:
▻ db.Employes.find({$and : [ { poste : "Ing"},
{ date_rect : {$gte : 2000}},
{ date_rect : {$lt : 2010}} ]},
{ nom : 1, _id : 0})

▻ 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

▰ Deux solutions pour exprimer un ‘OR’ :


▻ Avec l’opérateur ‘’$in’’ :
▻ db.Employés.find ( { date_rect : { $in [2000, 2002, 2004] } } ,
{ nom : 1, _id : 0})

▻ Equivalent à : SELECT nom


FROM Employés
WHERE date_rect in (2000, 2002, 2004)

51

17
15/10/2024

Opérateur OR

▰ Deux solutions pour exprimer un ‘OR’ :


▻ Avec l’opérateur ‘’$or’’ :
▻ db. Employés.find( { date_rect : 2000,
$or : [{salaire : {$lt : 100000}}, {NbAbsences : {$lt : 4}}]},
{nom : 1, _id : 0})

▻ Equivalent à : SELECT nom


FROM Employés
WHERE date_rect = 2000 AND (salaire < 10000) OR NbMaladie <4

52

Opérateur de test sur un élément


▰ $exist { fieldName : {$exists : boolean }}
▻ {nbAbsences : {$exists : true, $lt 4}} → Si le champ nbAbsences
existe, alors teste s’il est <4
▻ {nbAbsence : {$exists : false}} → Si le champ nbEntrees
n’existe pas alors retourne true

▰ $type { fieldName: {$type : BSON type number | String alias }}


▻ {nbAbsences : {$type : 16} }
▻ Remarque : type BSON numéro 16 (!) ‘’int’’
▻ {nbAbsences : {$type : ‘’int’’}} → Si le champ nbAbsences est de type int, alors
retourne true

53

▰ $mod { fieldName : { $mod : [ divisor, remainder ] }}


▻ {nbEtudiants : { $mod : [3, 0] }}

▻ Si le nombre d’étudiants est un multiple de 3, retourne true ( exemple pour voir si on


peut construire des trinômes )

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

▻ { regionName : { $regex : /lor/ , $options : ‘i’ } }


▻ si le nom de la région contient lor ou Lor ou LoR ou LOR alors retourne true
55

▰ $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

▰ Exemple: soir la collection articles


▰ { "_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.articles.createIndex({ content: "text" });


▻ db.articles.find({ $text: { $search: "MongoDB" } });
▻ Cette requête renverra tous les documents de la collection articles où le champ
content contient le mot "MongoDB"

57

19
15/10/2024

▰ Syntaxe générale de $text


▻ { $text : { $search : <string> ,
$language : <string> ,
$caseSensitive : <boolean>,
$diacriticSensitive : <boolean>}}
▰ $search: C'est le champ dans lequel vous spécifiez la chaîne de caractères que vous recherchez.
▰ $language: [optionnel] permet de spécifier la langue pour la recherche textuelle.
▰ $caseSensitive: [booléen optionnel. ]
▻ true, la recherche prendra en compte la casse (distinguer majuscules et minuscules).
▻ false (par défaut), la recherche est insensible à la casse.
▰ $diacriticSensitive: [booléen optionnel. ]
▻ true, la recherche prendra en compte les différences diacritiques (par exemple, la distinction entre "é" et "è"). 58

▰ 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

▰ Syntaxe du $where { fieldName : {


$where : JavaScript expression
}
}

▻ 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
}
}

▰ Exemple 2: { "_id": 1, "name": " Leila", "grades": [80, 90, 75] }


{ "_id": 2, "name": " Rym", "grades": [95, 92, 88] }
{ "_id": 3, "name": " Djawed", "grades": [60, 70, 55] }

▰ 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
}
}

▰ Exemple 3: { "_id": 1, "name": " Leila", "grades": [80, 90, 75] }


{ "_id": 2, "name": " Rym", "grades": [95, 92, 88] }
{ "_id": 3, "name": " Djawed", "grades": [60, 70, 55] }

▰ db.students.find({ $where: function ()


{ return (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.

63

21
15/10/2024

Opérateurs de test sur tableau

▰ $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…]
}
}

▻ Renverra true (retiendra l’enregistrement) si le champs arrayFieldName contient toutes


les valeurs listées ensuite (val1, val2 et val3).

64

Opérateurs de test sur tableau

▰ 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

Opérateurs de test sur tableau


▰ $elemMatch: permet de spécifier plusieurs critères pour filtrer les éléments d'un tableau.
▻ Syntaxe: { arrayFieldName : { $elemMatch: {query1, query2 …}}}
▻ arrayFieldName: le nom du champs tableau dans votre collection a interroger
▻ { query1, query2, ... }: Ce sont les critères à appliquer à chaque élément du tableau.
▻ Renverra true (retiendra l’enregistrement) si le champs arrayFieldName contient au moins un
élément satisfaisant toute les requêtes.

67

▰ Exemple 1: on cherche s’il y a au moins une note dans l’intervalle [7,10[


▻ Si le champs notes vaut [18, 8, 17, 11] → alors { notes : { $elemMatch : { $gte : 7, $lt
: 10 } } } renverra true

68

[ { "_id": 1, db.students.find({ grades: { $elemMatch:


"name": "Aline", { score: { $gt: 90 },
"grades": [ { "subject": "Mathématiques", "score": 92 }, subject: "Mathématiques"
{ "subject": "Physique", "score": 88 }, }
{ "subject": "Chimie", "score": 95 } ] }, }
{ "_id": 2, })
"name": "Nesrine",
"grades": [ { "subject": "Mathématiques", "score": 88 },
{ "subject": "Physique", "score": 90 },
{ "subject": "Chimie", "score": 94 } ] }, { "_id": 1,
"name": "Aline",
{ "_id": 3, "grades": [ { "subject": "Mathématiques", "score": 92 },
"name": "Ahmed", { "subject": "Physique", "score": 88 },
"grades": [ { "subject": "Mathématiques", "score": 94 }, { "subject": "Chimie", "score": 95 } ] },
{ "subject": "Physique", "score": 91 }, { "_id": 3,
{ "subject": "Chimie", "score": 89 } "name": "Ahmed",
"grades": [ { "subject": "Mathématiques", "score": 94 },
] { "subject": "Physique", "score": 91 },
}] { "subject": "Chimie", "score": 89 }
]
}
69

23
15/10/2024

Opérateurs de test sur tableau


▰ $size { arrayFieldName : { $size : theSize } }
▻ Renverra true (retiendra l’enregistrement) si le champ arrayFieldName a la taille indiquée.

[ { "_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

Opérateurs de test sur tableau


▰ $size { arrayFieldName : { $size : theSize } }
▻ Renverra true (retiendra l’enregistrement) si le champ arrayFieldName a la taille indiquée.
[ { "_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: { $gte: 2 }})
"name": "Nesrine",
"grades": [ { "subject": "Mathématiques", "score": 88 },
{ "subject": "Physique", "score": 90 },
{ "subject": "Chimie", "score": 94 } ] },
{ "_id": 3, [ { "_id": 1,
"name": "Aline",
"name": "Ahmed", "grades": [ { "subject": "Mathématiques", "score": 92 },
"grades": [ { "subject": "Mathématiques", "score": 94 }, { "subject": "Physique", "score": 88 },
{ "subject": "Chimie", "score": 89 } { "subject": "Chimie", "score": 95 } ] },
{ "_id": 2,
] "name": "Nesrine",
}] "grades": [ { "subject": "Mathématiques", "score": 88 },
{ "subject": "Physique", "score": 90 },
{ "subject": "Chimie", "score": 94 } ] },
{ "_id": 3,
"name": "Ahmed",
"grades": [ { "subject": "Mathématiques", "score": 94 },
{ "subject": "Chimie", "score": 89 }
]
}] 71

Application de méthodes aux collections

▰ 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

Application de méthodes aux collections

▰ Méthode sort : db.collectionName.find(query, projection).sort(sortCriteria)


▻ Ordonne les enregistrements d’une collection selon un ou plusieurs champs,
dans l’ordre croissant ou décroissant
db.laCollection.find(…).sort({‘’ChampsA’’ : 1, ‘’ChampsB’’ : ‐1})
▻ trie laCollection selon le champ ChampsA dans l’ordre croissant, et
pour un même champs ChampsA, trie selon champsB dans l’ordre
décroissant
▰ Attention : db.laCollection.sort({‘’a.b.c.d’’ : 1, ‘’a.b.x.y’’ : ‐1})

73

Application de méthodes aux collections

▰ Exemple sort : db.collectionName.find(query, projection).sort(sortCriteria)


▻ db.laCollection.find(…).sort({‘’ChampsA’’ : 1, ‘’ChampsB’’ : ‐1})
▻ trie laCollection selon le champ ChampsA dans l’ordre croissant, et pour
un même champs ChampsA, trie selon champsB dans l’ordre décroissant
▻ Exemple
[ { "_id": 1, "name": "Aline", "ChampsA": 20, "ChampsB": 30 },
{ "_id": 2, "name": "Bahia", "ChampsA": 20, "ChampsB": 25 }, db.students.find().sort({ 'ChampsA': 1, 'ChampsB': -1 })
{ "_id": 3, "name": "Cerine", "ChampsA": 15, "ChampsB": 35 },
{ "_id": 4, "name": "Dahmane", "ChampsA": 15, "ChampsB": 20 }
]

[ { "_id": 4, "name": "David", "ChampsA": 15, "ChampsB": 20 },


{ "_id": 3, "name": "Charlie", "ChampsA": 15, "ChampsB": 35 },
{ "_id": 2, "name": "Bob", "ChampsA": 20, "ChampsB": 25 },
{ "_id": 1, "name": "Alice", "ChampsA": 20, "ChampsB": 30 } ] 74

Application de méthodes aux collections

▰ Méthode count : db.laCollection.find(…).count()


▻ Compte le nombre d’ enregistrements d’une collection
▻ db.laCollection.find(…).count() Ou bien : db.laCollection.count()
▻ Retourne le nombre d’enregistrements (de documents JSON) dans la collection
▰ Exemple
▻ db.students.find().count()

75

25
15/10/2024

Agrégations
d’opérations avec
aggregate (…)

76

Framework d’agrégation (1)

▰ 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

Framework d’agrégation (1)

▰ 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 !

▰ Opérations pour l’agrégation :


$match $unwind $lookup
$project $sort
$group $limit 78

26
15/10/2024

Framework d’agrégation (1)

▰ db.collectionName.aggregate({op1}, {op2}, {op3}…)

▰ Opérations pour l’agrégation :


$match $unwind $lookup
$project $sort
$group $limit

79

Quand Utiliser Aggregate vs Find

▰ Quand utiliser find() :


▻ Requêtes simples : Recherche de documents avec des filtres, des projections
basiques et des tris.
▻ Pas besoin de transformations complexes sur les données.

▰ Exemple d'utilisation de find() :

db.commandes.find({ client: "FRIHI Mohamed" })

[
{ "client": "FRIHI Mohamed", "produit": "Livre", "quantité": 2 },
{"client": "FRIHI Mohamed", "produit": "Stylo", "quantité": 5 }
] 80

Quand Utiliser Aggregate vs Find

▰ Quand utiliser aggregate() :


▻ Requêtes complexes : Besoin de regrouper des données, effectuer des calculs, ou
manipuler des structures de tableaux.
▻ Manipulation des documents avec des transformations avancées (comme $group,
$unwind, $lookup).

▰ Exemple d'utilisation d'aggregate() :


db.commandes.aggregate([ { $match: { client: "FRIHI Mohamed" } },
{ $group: { _id: "$client", totalProduits: { $sum: "$quantité" } } }
])

[ { "_id": "FRIHI Mohamed" , "totalProduits": 7 } ] 81

27
15/10/2024

Framework d’agrégation (3)

▰ $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.

▰ Syntaxe de base de $match


▻ La syntaxe de $match est identique à celle de find(), basée sur des expressions et des
opérateurs de comparaison.
▻ Exemple : { $match: { "client": "FRIHI Mohamed" } }
▻ Ce filtre sélectionnera uniquement les documents où le champ client a la valeur
FRIHI Mohamed
82

Framework d’agrégation (3)

▰ $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

Framework d’agrégation (3)

▰ $match : Utilisation de $match avec des Champs Imbriqués


▻ $match peut filtrer sur des champs imbriqués à l'intérieur de sous-documents.

▻ Exemple 2: collection Commande


[
{ "client": "frihi Mohamed", "adresse": { "ville": "Alger", "codePostal": 16000 } },
{ "client": "BENALIA AHMED", "adresse": { "ville": "Oran", "codePostal": 31000 } }
]

▻ Sélectionner les commandes dont le client vit à Alger.


▻ db.commandes.aggregate([ { $match: { "adresse . ville": "Alger" } } ])
[
{ "client": "frihi Mohamed", "adresse": { "ville": "Alger", "codePostal": 16000 } }
]
84

28
15/10/2024

Framework d’agrégation (3)


▰ $match :
▻ Exemple 3: Nombre Employés Recrutés après 2007
▻ db.getCollection('employes').aggregate ([ {"$match" : {"date_recrutement" : { $gt : 2007}}},
{ $group: { _id: null, count: { $sum: 1 } } }])
▻ Equivalent à : SELECT COUNT(*) AS count
FROM employes
WHERE date_recrutement > 2007;
[
{ "nom": "Aliane Ali", "poste": "Développeur", "date_recrutement": 2005 },
{ "nom": "Benalia ahmed", "poste": "Analyste", "date_recrutement": 2008 }, [
{ "nom": "FRiHi Mohamed", "poste": "Manager", "date_recrutement": 2010 }, { "_id": null, "count": 3 }
{ "nom": "Dahmani Naim", "poste": "Technicien", "date_recrutement": 2006 }, ]
{ "nom": "Zemirli Hamid", "poste": "Designer", "date_recrutement": 2009 }
] 85

Framework d’agrégation (3)

▰ $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 } ]);

▰ Equivalent à : SELECT produit, SUM(quantite) AS ventesTotales


FROM ventes
WHERE date >= '2022-01-01’
GROUP BY produit
ORDER BY ventesTotales DESC LIMIT 5;
86

▰ $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 } ]);

{ "produit": "A", "ventesTotales": 30, "date": "A" }


{ "produit": "B", "ventesTotales": 15, "date": "B" }
89

▰ $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

▰ $limit : Permet de limiter le nombre de réponses aux plus importantes Exemple : on


s’interesse qu’aux 4 fonctions les plus demandées
db.employes.aggregate( {"$match" : {"annee_recrutement" : {$gt : "2011"}}},
{"$project" : {"fonction" : 1, "annee_recrutement" : 1}}, {"$group" : {_id : "$fonction",
"debut" : {$min : "$annee_recrutement" "},
"occurences" : {$sum : 1}}}, {"$sort" : {"occurences" : ‐1}}, {"$limit" : 4} ).pretty()

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

Vous aimerez peut-être aussi