RESUME DE COURS NO-SQL
Exercice 1
1. Objectif principal de la réplication + rôle de l’arbitre
La réplication assure la haute disponibilité et la tolérance aux pannes en gardant plusieurs copies des données
sur plusieurs nœuds (si un serveur tombe, un autre prend le relais).
L’arbitre ne stocke pas de données, il sert à voter lors des élections pour aider à choisir un nouveau primary
en cas de panne.
2. Rôle du signal heartbeat dans un système de réplication
Le heartbeat est un signal périodique échangé entre les nœuds pour vérifier qu’ils sont actifs et connaître leur
état. S’il n’y a plus de heartbeat d’un nœud, le replica set considère qu’il est indisponible et peut déclencher
une élection.
3. À quoi sert explain dans une requête
Explain sert à montrer comment MongoDB exécute la requête (plan d’exécution), surtout si un index est utilisé
ou si MongoDB fait un scan complet, afin d’optimiser la performance.
4. Quand est-ce qu’on ne peut pas utiliser les jointures entre 2 collections
On ne peut pas faire une jointure avec une simple requête find ; la jointure se fait via l’agrégation avec $lookup.
Elle ne marche pas entre deux bases différentes, et elle est limitée quand les collections sont shardées.
5. Comment vérifier si des utilisateurs ont été créés dans MongoDB
On peut afficher la liste des utilisateurs avec show users ou [Link]().
Excerice 2
1. Afficher les commandes dont le montant est supérieur à 1000
[Link]([
{ $match: { "[Link]": { $gt: 1000 } } }
])
2. Afficher toutes les commandes passées par le client dont le nom est "LAHLOU"
[Link]([
{ $match: { "[Link]": "LAHLOU" } }
])
3. Afficher les commandes dont le statut n’est pas "Annulée"
[Link]([
{ $match: { "[Link]": { $ne: "Annulée" } } }
])
4. Afficher uniquement le nom, prénom et email du client
[Link]([
{
$project: {
_id: 0,
"[Link]": 1,
"[Link]": 1,
"[Link]": 1
}
}
])
5. Afficher les commandes triées par montant décroissant
[Link]([
{ $sort: { "[Link]": -1 } }
])
6. Afficher les 3 commandes les plus coûteuses passées par le client "BENNANI-SMIRESS Kabbour"
[Link]([
{ $match: { "[Link]": "BENNANI-SMIRESS",
"[Link]": "Kabbour" } },
{ $sort: { "[Link]": -1 } },
{ $limit: 3 }
])
7. Afficher le nombre de commandes regroupées par statut
[Link]([
{
$group: {
_id: "$[Link]",
nombre: { $sum: 1 }
}
}
])
8. Calculer le montant moyen des commandes
[Link]([
{
$group: {
_id: null,
montantMoyen: { $avg: "$[Link]" }
}
}
])
9. Calculer le chiffre total des commandes
[Link]([
{
$group: {
_id: null,
chiffreTotal: { $sum: "$[Link]" }
}
}
10. Afficher la somme des montants de toutes les commandes par client
[Link]([
{
$group: {
_id: { id: "$[Link]", nom: "$[Link]", prenom: "$[Link]" },
totalMontant: { $sum: "$[Link]" }
}
}
])
11. Afficher le nombre de commandes par livreur
[Link]([
{
$group: {
_id: { id: "$[Link]", nom: "$[Link]", prenom: "$[Link]" },
nombreCommandes: { $sum: 1 }
}
}
])
[Link] les livreurs ayant effectué plus de 2 commandes
[Link]([
{
$group: {
_id: { id: "$[Link]", nom: "$[Link]", prenom: "$[Link]" },
nombreCommandes: { $sum: 1 }
}
},
{ $match: { nombreCommandes: { $gt: 2 } } }
])
13.Décomposer les produits de chaque commande et compter combien de fois chaque produit a été
commandé
[Link]([
{ $unwind: "$produits" },
{
$group: {
_id: "$[Link]",
nombreFoisCommande: { $sum: 1 }
}
}
])
Partie Sécurisation
[Link]éer un utilisateur gestionnaire (mot de passe : gest123, rôle : lecture/écriture uniquement sur la
base de données qui contient la collection commandes).
use nom_db
[Link]({
user: "gestionnaire",
pwd: "gest123",
roles: [{ role: "readWrite", db: "nom_db" }]
})
Partie Géolocalisation
[Link] les 100 commandes les plus proches du point [-7.618867, 33.597941] et qui ont été livrées
[Link]([
{
$geoNear: {
near: { type: "Point", coordinates: [-7.618867, 33.597941] },
key: "[Link]",
distanceField: "distance",
spherical: true
}
},
{ $match: { "[Link]": "Livrée" } },
{ $limit: 100 }
])
SECURISATION MONGODB
La sécurisation consiste à contrôler qui peut se connecter et ce qu’il a le droit de faire. MongoDB utilise des rôles (read,
readWrite, userAdminAnyDatabase, readWriteAnyDatabase, etc.) qu’on attribue aux utilisateurs sur une base précise
(db) ou globalement.
Créer un admin global
use admin
[Link]({
user: "lpadmin",
pwd: passwordPrompt(),
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
})
Créer des utilisateurs avec droits limités (par base)
util1 : lecture sur au1, lecture+écriture sur au2
use admin
[Link]({
user: "util1",
pwd: passwordPrompt(),
roles: [
{ role: "read", db: "au1" },
{ role: "readWrite", db: "au2" }
]
})
util2 : lecture sur au2
use admin
[Link]({
user: "util2",
pwd: passwordPrompt(),
roles: [
{ role: "read", db: "au2" }
]
})
Modifier les rôles d’un utilisateur
Ajouter un rôle
use admin
[Link]("util1", [
{ role: "readWrite", db: "au1" }
])
Retirer un rôle
use admin
[Link]("util1", [
{ role: "read", db: "au3" }
])
Voir les infos d’un user
use admin
[Link]("util1")
COORDONNEES GEOSPATIALES MONGODB
Les données géospatiales sont des informations associées à des coordonnées géographiques
(latitude, longitude, altitude) et qui permettent de représenter, analyser et comprendre l’espace
géographique.
Exemples concrets
• La position d’un restaurant sur Google Maps
Les données géospatiales permettent de représenter des positions géographiques (latitude,
longitude) et d’effectuer des requêtes spatiales comme :
• trouver les points proches d’un lieu
• vérifier si un point est dans une zone
• calculer des distances
MongoDB fournit un support natif puissant pour ce type de données.
Formats géospatiaux dans MongoDB
Point
{
"type": "Point",
"coordinates": [longitude, latitude]
}
Important : l’ordre est toujours [longitude, latitude].
Autres types GeoJSON
• LineString
• Polygon
• MultiPoint
• MultiPolygon
Stocker la position en GeoJSON Point (ordre obligatoire)
{
"type": "Point",
"coordinates": [-73.986829, 40.759216]
}
Créer l’index 2dsphere (sinon requêtes geo échouent)
[Link]({ location: "2dsphere" })
Requête proche (find + $near)
$maxDistance est exprimé en mètres.
[Link]({
location: {
$near: {
$geometry: { type: "Point", coordinates: [-73.986829, 40.759216] },
$maxDistance: 5000
}
}
})
Requête proche + autre condition (ex: cuisine)
[Link]({
"[Link]": {
$near: {
$geometry: { type: "Point", coordinates: [-73.986829, 40.759216] },
$maxDistance: 500
}
},
cuisine: "Indian"
})
Aggregation ($geoNear)
Règle: $geoNear doit être le premier stage
[Link]([
{
$geoNear: {
near: { type: "Point", coordinates: [-73.986829, 40.759216] },
key: "[Link]",
distanceField: "distance",
maxDistance: 500,
spherical: true
}
},
{ $match: { cuisine: "Indian" } },
{ $count: "number" }
])
Recherche dans une zone ($geoWithin Polygon)
[Link]({
"[Link]": {
$geoWithin: {
$geometry: {
type: "Polygon",
coordinates: [[
[-7.0, 33.9],
[-6.7, 33.9],
[-6.7, 34.1],
[-7.0, 34.1],
[-7.0, 33.9]
]]
}
}
}
})
EXAM 2025
1. Donner la liste de tous les objets livrés entre 2024-01-29T21:00:00 et 2024-01-30T00:00:00 (uniquement le
champ objet et sans répétition).
[Link]([
{ $match: { d_livraison: { $gte: ISODate("2024-01-29T21:00:00"), $lte:
ISODate("2024-01-30T00:00:00") } } },
{ $group: { _id: "$objet" } }
])
2. Donner le nombre de chaque type de moyen de transport utilisé par les livreurs.
[Link]([
{ $group: { _id: "$typeTrans", count: { $sum: 1 } } }
])
3. Donner la liste de tous les noms de livreurs qui ont livré entre 2024-02-04T21:00:00 et 2024-02-05T00:00:00
(sans répétition).
[Link]([
{ $match: { d_livraison: { $gte: ISODate("2024-02-04T21:00:00"), $lte:
ISODate("2024-02-05T00:00:00") } } },
{ $lookup: {
from: "livreur",
localField: "id_livreur",
foreignField: "_id",
as: "livreur_details"
}
},
{ $unwind: "$livreur_details" },
{ $group: { _id: "$livreur_details.nom_prenom" } }
])
4. Donner le nom de tous les livreurs qui ont livré dans l’avenue "elite".
[Link]([
{ $match: { "adr_livraison.avenue": "elite" } },
{ $lookup: {
from: "livreur",
localField: "id_livreur",
foreignField: "_id",
as: "livreur_details"
}
},
{ $unwind: "$livreur_details" },
{ $project: { _id: 0, nom_prenom: "$livreur_details.nom_prenom" } }
])
5. Compter le nombre de livraisons effectuées par le livreur "yassine chihab".
[Link]([
{ $lookup: {
from: "livreur",
localField: "id_livreur",
foreignField: "_id",
as: "livreur_details"
}
},
{ $match: { "livreur_details.nom_prenom": "yassine chihab" } },
{ $count: "nombreLivraisons" }
])
6. Donner le nom du livreur qui a eu le nombre maximal des notes de satisfaction.
[Link]([
{ $group: { _id: "$id_livreur", maxSatisfaction: { $max: "$satisfaction" }
} },
{ $lookup: {
from: "livreur",
localField: "_id",
foreignField: "_id",
as: "livreur_details"
}
},
{ $unwind: "$livreur_details" },
{ $project: { _id: 0, nom_prenom: "$livreur_details.nom_prenom",
satisfaction: "$maxSatisfaction" } }
])
AGGREGATION (MongoDB)
L’agrégation permet de diviser une requête en étapes (stages). Chaque étape fait une opération (filtrage, projection,
tri, regroupement, etc.). C’est une pipeline.
Syntaxe : [Link]([ etape1, etape2, etape3 ])
Comparaison avec find [Link]({ city: "BOSTON" })
Equivalent en aggregation : fil1 = { $match: { city: "BOSTON" } }
[Link]([ fil1 ])
Stages importants dans la pipeline
• $match (filtrage)
Utilise les opérateurs de comparaison :
$gt (>) $gte (>=) $lt (<) $lte (<=) $ne (!=) $eq (=)
Ex :
fil1 = { $match: { city: "BOSTON" } }
fil2 = { $match: { "[Link]": { $lt: 10 } } }
[Link]([ fil1 ])
• $project (projection)
Choisir les champs à afficher ou cacher.
Ex :
proj1 = { $project: { _id: 0, name: 1, "[Link]": 1 } }
[Link]([ proj1 ])
• $sort (tri)
1 = croissant, -1 = décroissant.
Ex :
tr1 = { $sort: { "[Link]": -1 } }
[Link]([ tr1 ])
• $count (comptage)
Retourne le nombre de documents en sortie de pipeline.
Ex :
c1 = { $count: "number" }
[Link]([ fil1, c1 ])
• $limit (limite)
Limiter le nombre de résultats.
Ex :
lim1 = { $limit: 5 }
[Link]([ fil1, lim1 ])
• $skip (saut)
Ignorer N documents (pagination).
Ex :
sk1 = { $skip: 3 }
[Link]([ fil1, sk1, lim1 ])
• $group (regroupement)
Regrouper par une clé (_id = clé de regroupement, pas le _id du document).
Somme : { $sum: "$champ" }
Compter : { $sum: 1 }
Ex distinct par état :
grp1 = { $group: { _id: "$state" } }
[Link]([ grp1 ])
Ex somme population par état :
grp2 = { $group: { _id: "$state", population: { $sum: "$pop" } } }
[Link]([ grp2 ])
Ex compter nombre de zips par état + top 1 :
grp3 = { $group: { _id: "$state", n_zips: { $sum: 1 } } }
tr1 = { $sort: { n_zips: -1 } }
lim1 = { $limit: 1 }
[Link]([ grp3, tr1, lim1 ])
• $unwind (éclater un tableau)
Transformer un champ tableau en plusieurs documents (pour filtrer/grouper sur les éléments).
Ex :
eclater = { $unwind: "$grades" }
grp = { $group: { _id: "$[Link]", nombre: { $sum: 1 } } }
[Link]([ eclater, grp ])
Differnce entre base de donnees admin et local
admin : Contient des informations d'administration, comme les utilisateurs, les rôles, et les configurations des bases
de données. C'est la base centrale utilisée pour la gestion de l'authentification et des autorisations.
local : Utilisée pour stocker des informations internes au serveur MongoDB, comme les journaux d'opérations de
réplication et d'index. Elle contient également des informations pour le suivi des opérations locales, comme le
journal des écritures dans le cadre de la réplication.
$unwind
Le $unwind est une étape du pipeline d'agrégation qui permet de décomposer un tableau dans un document en
plusieurs documents distincts. Chaque élément du tableau devient un document séparé. Cela est utile lorsque l’on
veut travailler avec des données de type tableau, par exemple pour effectuer des agrégations ou des recherches sur
chaque élément individuellement.
explain()
On peut utiliser la méthode explain() pour mesurer les performances d'une requête. Elle fournit des informations
détaillées sur le plan d'exécution de la requête, y compris :
• Le type de scan effectué (index, collection scan),
• Les index utilisés,
• Le temps total d'exécution,
• Le nombre de documents analysés.
• Cela permet d'identifier les problèmes de performance et d'optimiser les requêtes.
la différence entre la sauvegarde/restauration et l’importation/exportation.
• Sauvegarde/restauration : La sauvegarde (mongodump) crée une copie des données d'une base de données
(y compris les index et autres métadonnées). La restauration (mongorestore) permet de récupérer une base
de données sauvegardée.
• Importation/exportation : Utilise mongoimport et mongoexport pour importer ou exporter des données au
format JSON, CSV ou TSV. Ces outils ne sauvegardent pas les index ni les autres métadonnées, et sont plus
adaptés pour les échanges de données entre systèmes.
Indexation
• Index : Structures de données spéciales pour résolution efficace des requêtes
• Sans index : MongoDB doit scanner tous les documents (inefficace)
• Avec index : Accès rapide via structure ordonnée
• Inconvénients des index
• Diminuent performances en mise à jour
• Ajoutent du volume à la base
Sécurisation des données
Authentification : Vérification de l'identité d'un client
Autorisation : Détermination de l'accès aux ressources et opérations
Modes de fonctionnement
1. Sans authentification (par défaut)
• Pas de login/mot de passe
• Dangereux
• À réserver environnements sécurisés
2. Avec authentification
• Configuration dans fichier de configuration
• Création d'utilisateurs obligatoire