Bases de données NoSQL
Chapitre 2: MongoDB
Dr. Mouna Chebbah
2021-2022
Plan
1. Introduction
2. Opérations CRUD
3. Pipeline d’aggrégation
Introduction
!MongoDB est l'un des systèmes « NoSQL » les plus populaires:
!Il fait partie des NoSQL dits « documentaires » (avec CouchDB);
!Il s'appuie sur un modèle de données semi-structure (encodage JSON) ;
!Il n’a pas de schéma (flexibilité complète);
!C’est un langage d'interrogation original (et spécifique) ;
!Il n’a pas (ou très peu) de support transactionnel.
!Construit dès l'origine comme un système scalable et distribué:
!distribution par partitionnement (sharding) ;
!technique adoptée: découpage par intervalles (type BigTable, Google) ;
!tolérance aux pannes par réplication.
Outils MongoDB
!MongoDB Compass: Interface graphique pour MongoDB permettant:
!exploration visuelle des données
!interaction avec les données avec la fonctionnalité CRUD complète
!exécution des requêtes ad-hoc en quelques secondes
!afficher et optimiser les performances des requêtes
!MongoDB Atlas: Serveur de données MongoDB assurant le stockages des
données en cloud
!Shell Mongo: Interface JavaScript interactive pour MongoDB permettant une
interrogation et mettre a jour des données, ainsi que les opérations
d'administration
Structure d’une BDD Mongo
!Une bases de données est un ensemble de collections
!Chaque collection regroupe un ensemble de documents
!La base de données et ses collections définissent un « namespace »
!Le schéma est le modèle de données des documents dans une collection
Qu’est ce qu’un document?
Un document est la représentation d'une donnée en BSON.
BSON = Binary JSON: Extension du JSON.
!JSON: Java Script Object Notation.
!JSON est un format fréquemment utilisé pour représenter les documents.
Documents JSON
Un document JSON est compose d'un ensemble de champs délimite par
des accolades: { champs }
!Un champ est un couple clé:valeur
!Toutes les clés sont entourées de guillemets « »
!Les clés et les valeurs sont séparés par 2 points :
!Les différents champs sont sépares par une virgule ,
Documents JSON
Les documents JSON peuvent contenir différents types de valeurs:
!String: chaîne des caractères entourée de de double quotes. L'espace est considéré
comme caractère.
!Number: Réel a virgule flottante.
!Boolean: true/false.
!Null.
!Object: sous-documents. Les documents peuvent être imbriques sur plusieurs
niveaux.
!Array: tableau délimite par des crochets. Les tableaux contiennent des valeurs
ordonnées séparées par des virgules.
Exemple
{"nom": "Phoenix", "prenom" : "Joaquim", =>Des chaînes de caractères
"couleurs preferees" : ["vert", "marron"]}=> Un tableau
Sachant que la valeur d'une paire clé/valeur peut être un objet (document) et que le tableau peut contenir
des objets (des documents), on peut ordonner les informations sur plusieurs niveaux.
Exemple:
{"acteur": {
"nom": "Phoenix", "prenom" : "Joaquim" },
"roles" : [
{"personnage" : "Theodore", "Film" : "her" },
{"personnage" : "Leonard Kraditor", " Film" : "Two Lovers"}
]
}
BSON
• Les documents ne sont pas directement stockés dans la base de données en
JSON mais dans un format binaire appelé BSON.
• BSON est une extension de JSON qui fournit des types de données
supplémentaires (tel que les dates) et des champs ordonnés. C'est un
format efficace pour le codage et décodage dans des langages différents.
• Les fichiers BSON sont dans un format binaire, donc illisible par les
utilisateurs.
Installation (linux)
Installation du Shell Mongo:
1. wget -qO - [Link] | sudo apt-key add –
2. sudo apt-get install gnupg
3. wget -qO - [Link] | sudo apt-key add –
4. echo "deb [ arch=amd64,arm64 ] [Link] focal/mongodb-
org/4.4 multiverse" | sudo tee /etc/apt/[Link].d/[Link]
5. sudo apt-get update
6. sudo apt-get install -y mongodb-org
7. ps --no-headers -o comm 1
8. Si systemd: sudo systemctl start mongod
9. sudo systemctl status mongod
10. sudo systemctl enable mongod
Installation (linux)
1. sudo systemctl stop mongod
2. sudo systemctl restart mongod
3. Lancer le shell MongoDB avec mongo
Installation de MongoDB Compass:
1. Télécharger MongoDB Compass:
[Link]
2. L’installer
Exploration des données
Connectez vous au cluster de données à partir de MongoDB Compass:
mongodb+srv://NoSQL:NoSQL@[Link]/test
Explorez les types de données de la collection « movieDetails » de la base
vidéo
1. Le schéma de la collection est visualisable a partir de l'onglet « Schema »
Shell Mongo
!La commande mongo lance l’interpréteur de commandes (Shell Mongo).
!Pour lancer le Shell Mongo, ouvrez une invite de commande pour lancer
l'interpréteur de commandes mongo
!mongo vous permet de travailler en local
!Pour vous connectez à un serveur de données Atlas, utilisez la commande:
mongo "mongodb+srv://[Link]/myFirstDatabase" --
username NoSQL
!Vous serez connecté à un serveur de base de données
Opérations CRUD
MongoDB facilite les opérations CRUD:
!Create: Ajout de nouveaux documents;
!Read: Recherche de documents selon des filtres. Correspond à la sélection et
projection de documents;
!Update: Mise-à-jour de documents;
!Delete: Suppression de documents.
!Remarque: Compass ne supporte pas toutes les requêtes de MongoDB.
!Il faut utiliser le Shell.
Création d’une collection
!Dans mongodb, une base de données contient des collections dans
lesquelles s'ajoutent les documents de même nature.
!La création d'une collection se fait avec:
1. MongoDB Compass: en se faisant guidé par son interface graphique.
Création avec Compass
!Insertion d'un premier document dans la collection vide movieScratch:
!Insérer un premier document:
Création avec le Shell
2. Shell Mongo: création implicite a l'insertion du premier document.
!La création d'une base de données se fait implicitement lors de la création de sa
première collection.
!La création d'une collection se fait implicitement avec l'insertion d'un premier
document.
!Pour afficher toutes les bases de données: show dbs
!Pour sélectionner la base de données a utiliser: use <nomBDD>
!Pour lister les collections d'une base de données: show <collections>
!Nommer la base de données en cours d'utilisation: db
Création avec le Shell
!Il faut commencer par sélectionner la base de données dans laquelle vous
voulez modifier/interroger une collection:
use <nomBDD>
!Si la base de données spécifiée <nomBDD> n'existe pas, elle sera
réellement crée a la première insertion de document.
Insertion d'un document avec le Shell Mongo:
db. <nom de la collection>.insertOne(<document>)
!Si la collection n'existe pas, elle sera crée a l'insertion du premier
document.
Exemple
Dans cet exemple nous allons travailler en local (mode Standalone):
1. Lancez le Shell Mongo avec la commande mongo
2. show dbs listera les bases de données existante
3. use test permettra de créer une première base de données nommée test
4. [Link](
{"title":"Rocky","year":1976,"imdb":"tt0075148"})
Permettra de créer une collection « movieScratch » dans la base de données
test en insérant un premier document:
{"title":"Rocky","year":1976,"imdb":"tt0075148"}
Exemple
Remarquez que la requête retourne un message de type:
{
"acknowledged" : true, => l’opération d'insertion a réussi
"insertedId" : ObjectId("5daee84199d97132d833f03b") =>L'identifiant
unique du document inséré
}
Vérifiez que la base de données test et la collection movieScratch ont bien
été crée.
ObjectId
!Chaque document doit avoir un identifiant unique id dans la collection.
!Si l'indentifiant _id n'est pas fourni lors de l'insertion du document, MongoDB
ajoutera un de type ObjectId.
!Il est possible d’insérer un document tout en fournissant une valeur d'identifiant.
Exemple:
[Link]( {_id:"tt0075148"
,"title":"Rocky","year":1976,"imdb":"tt0075148"})
!La collection movieScratch convient 2 documents avec les mêmes informations
mais leur id sont différents. Les identifiant id des 2 documents sont de types
différents: Chaîne de caratères (String) et ObjectID.
Insertion de plusieurs documents
!Au lieu d’insérer un seul document passé en paramètre, un ensemble de
documents organisés dans un tableau peut être inséré en une seule instruction
comme suit:
db. <nom de la collection>.insertMany([{document1},{document2}, . . . ]
,{"ordered":false})
!Insertion ordonnée (par défaut): insère les documents dans l'ordre. L'insertion
s’arrête en cas d'erreur.
!En cas d'erreur, tous les documents a partir de celui qui a généré cette erreur ne
sont pas insérés.
!Insertion non ordonnée (spécifié par {"ordered":false}): l'insertion continue
même en cas d'erreur. Uniquement le document générant une erreur n'est pas
inséré.
Exemple
Insérez les 2 documents suivants:
1. {
"title":"Creed",
"year":2015,
"imdb":"tt3076658"
}
2. {
"title":"Star Trek II: The Worth of Khan",
"year":1982,
"imdb":"tt0084726"
}
Filtrer les documents
Les filtres sur Compass:
!Sélectionner la base de données et la collection sur laquelle le filtre sera applique
!Le filtre s’écrit dans l'espace qui lui est réservé comme suit:
{" Champ " :valeur}
!Les documents qui vérifie la condition d’égalité sont sélectionnés
!Deux conditions peuvent être couplé en les séparant par une virgule ,
!Uniquement le ou les documents vérifiant la ou les conditions seront sélectionnés.
Exemple
Les filtres suivants permettent de sélectionner des films de la collection
movieDetails de la base de données video:
!{year:1968}: sélectionne les films produit en 1968;
!{year:1968,type:"movie"}: sélectionne les films de type « movie »
produit en 1968;
!{year:1968,type:"movie",rated:"G"}: sélectionne les films de type
« movie » produit en 1968 et de classe « G ».
Filtrer les documents
Pour appliquer un filtre sur une collection avec le Shell Mongo:
1. Sélectionner la base de données
2. db. <collection>.find({Champ:"valeur"})
Exemples:
1. use video
2. [Link]({year:1968}): sélectionne les films produit en 1968.
3. [Link]({year:1968,type:"movie"}): sélectionne les films de type
« movie » produit en 1968.
4. [Link]({year:1968,type:"movie",rated:"G"}): sélectionne les
films de type movie produit en 1968 et de classe « G ».
Filtrer les sous-documents
Pour appliquer un filtre sur un champ d'un sous-document, il faut utiliser la
notation orientée objet.
1. Sous Compass:
{"Champ.<Champ sous document>":valeur}
2. Avec le Shell Mongo:
db. <collection>.find({"Champ.<Champ sous document>":valeur})
Exemple
Sous Compass:
!{"[Link]":8.3}: la valeur du champ « imdb » est un document
(Object) dont rating est l'un des sous-champs.
!{"[Link]":8.3,"[Link]":0}: « awards » a comme valeur des
documents dont « wins » est l'un des champs
Avec le Shell Mongo:
[Link]({"[Link]":8.3})
[Link]({"[Link]":8.3,"[Link]":0})
Filtre sur les tableaux
Pour appliquer un filtre sur un champ admettant un tableau comme valeur, il faut
utiliser la notation suivante:
Sous Compass:
{"Champ" :[valeur1,valeur2,. . . ]}
Avec le Shell Mongo:
db. <collection>.find({"Champ" :[valeur1,valeur2,. . . ]})
Remarque: Ce type de filtre cherche les documents dont la valeur du champ de
type tableau correspond exactement au tableau spécifié dans le filtre.
Exemple
Sous Compass:
!{genres:["Western"]}: filtre les documents dont la valeur de l'attribut genres est
un tableau contenant exactement une seule valeur « Western ».
!{writers:["Paul Monash","Erich Maria Remarque"]}: filtre les documents dont
la valeur de l'attribut writers est un tableau contenant exactement "Paul Monash"
et "Erich Maria Remarque" dans le même ordre.
Avec le Shell Mongo:


Filtre sur les tableaux
Sous Compass:
{"Champ":{$all:[valeur1,valeur2,. . . ]}}
Avec le Shell Mongo:
db. <collection>.find({<Champ> :{$all:[valeur1,valeur2,. . . ]}})
!Filtre les documents dont l'attribut champ contient les valeurs [valeur1, valeur2,.
. . ] dans n'importe quel ordre.
!L'essentiel est que au moins toutes les valeurs [valeur1, valeur2,. . . ] font partie
de la valeur du champ.
Exemple
Sous Compass:
!{genres:{$all:["Western"]}}
!{writers:{$all:["Paul Monash","Erich Maria Remarque"]}}
Avec le Shell Mongo:


Filtre sur les tableaux
Pour filtrer les documents ayant une valeur donnée à une position donnée
d'un champ de valeur tableau:
Sous Compass:
{ "<[Link]>" :valeur}
Avec le Shell Mongo:
db. <collection>.find({ "<[Link]>" :valeur})
Exemple
Sous Compass:
!{"genres.0":"Western"}: Filtre les documents telle que Western apparaît a la
première position dans le tableau valeur du champ genres.
!{"genres.0":"Western","countries.1":"USA"}: Filtre les documents telle que
« Western » apparaît a la première position dans le tableau valeur du champ
« genres » et la valeur « USA » apparaît a la deuxième position dans le tableau
valeur du champ countries.
Avec le Shell Mongo:


Projection
!Par défaut, MongoDB retourne tous les champs de tous les documents qui
correspondent au filtre.
!Projection: limiter les champs retournés par une requête (un filtre).
!La projection est le deuxième argument de la méthode find.
!Syntaxe:
!db. <collection>.find({. . . },{<champ1>:0, <champ2>:1, . . . })
!Les champs à retenir sont suivi par :1 dans le second argument de find.
!Les champs à exclure sont suivi par :0 dans le second argument de find.
!Si au moins un seul champ est retenu, tous les autres champs sont retiré sauf le _id. Il faut
retirer manuellement le id.
!Si au moins un seul champ est retiré, tous les autres champs ont retenus.
Exemple





Questions
Pour répondre à ces questions utilisez la collection « movieDetails » de
la base de données vidéo:
1. Quels sont les différents type de film? [ "movie" ]
2. Quel est le nombre de documents dont l'image du « tomato » est " certified" ? 137
3. Quel est le nombre de documents dont l'image du « tomato » est " certified" et a
gagne exactement 4 « awards »? 3
4. Quel est le nombre de documents écrits par "John Orloff" et "Mariane Pearl"? 1
5. Quel est le nombre de films dans lesquels "Angelina Jolie" a joué un rôle? 5
6. Quel est le nombre de films dans lesquels "Angelina Jolie" et "Brad Pitt" ont joue un
rôle ensemble? 1
7. Quel est le titre de ce film? { "title" : "Mr. & Mrs. Smith" }
Opérateurs de comparaison
Ils permettent de filtrer les documents sur la base de la valeur d’un attribut
relativement à une valeur fixe
Syntaxe:
db. <collection>.find({Attribut:{$op:valeur}})
!$op: spécifie la relation que doit vérfier la valeur d'un attribut par rapport a une autre
valeur. Des exemple de $op:
!$gt : plus grand que
!$lt : plus petit que
!$gte : plus grand ou égal a
!$lte: plus petit ou égal a
!$ne: non égal
!$in: inclus dans
!$nin: n'est pas inclus dans
Exemples



.pretty()



$exists
!Les documents stockés dans une collection peuvent avoir différentes clés (attributs).
!Certaines clés peuvent exister dans certains documents et pas dans d'autres.
!$exists permet de filtrer les documents contenant un attribut spécifique.
Exemple 1:
[Link]({"[Link]":{$exists:true}},{"[Link]":1,title:1,
_id:0})
Exemple 2:
[Link]({"[Link]":{$exists:false}},{"[Link]":1,title:
1,_id:0})
Exemple 3:
[Link]({"[Link]":null},{"[Link]":1,title:1,_id:0})
$type
!Filtre les documents ayant un type de données particulier pour une clé
donnée.
!Particulièrement utile pour les attributs ayant différents type de valeurs.
Exemple:
[Link]({"[Link]":{$type:"string"}},{"[Link]
ensus":1,title:1,_id:0})
Opérateurs logiques
!$or combine des conditions dont une seule suffit pour sélectionner les
documents.
!$or prend un tableau comme argument; les éléments du tableau sont les
conditions qu'il suffit de satisfaire au moins une d'entre elles pour que le
document soit sélectionné.
Exemple:
[Link]({$or:[{" [Link]":{$gt:95}},{"metacritic"
:{$gt:88}}]},{"[Link]":1,"metacritic":1,title:1,_id:0})
Opérateurs logiques
!$and spécifie des conditions que les documents doivent satisfaire simultanément pour être
sélectionnés.
!Filtre les documents qui vérifient toutes les conditions spécifiées.
!$and prend également un tableau comme argument.
Exemple:
[Link]({$and:[{"[Link]":{$gt:95}},{"metacritic":{$gt:88}}]},{"to
[Link]":1,"metacritic":1,title:1,_id:0})
Equivalent à:
[Link]({"[Link]":{$gt:95},"metacritic":{$gt:88}},{"[Link]":
1,"metacritic":1,title:1,_id:0})
Question: Quelle est l'utilité de $and?
Opérateurs de tableaux
!$all compare les valeurs d'un attribut de type tableau à un tableau d’éléments.
Exemple 1:
[Link]({genres:{$all:["Comedy","Crime","Drama"]}},{genres:1,title:1,_id
:0})
!Uniquement les documents contenant au moins « Comedy » , « Crime » et « Drama »
dans l’attribut « genres » sont filtres.
!$size est utilisé pour filtrer des documents sur la base de la taille d'un tableau valeur
d'un attribut.
Exemple 2:
.pretty()
Opérateur d’évaluation
MongoDB support un operateur de requête permettant d'utiliser une
expression régulière $regex pour comparer des valeurs d'attributs a des
chaînes de caractères.
Exemple:
[Link]({"[Link]":{$regex:/^Won.*/}}).pretty()
Questions
Utilisez la collection « movies » de la base de données « video » pour répondre à ces questions:
1. Combien de documents avez vous dans la collection movies?
2. Affichez le 10ème document.
3. Quel sont les films qui ont été dirigé par Tarantino (Tarantino est le nom de famille)?
4. Donnez le film le plus ancien ensuite le plus récent.
5. De quelle année sont-ils (le film de plus ancien et le plus récent?
6. Donnez les titres des films produits entre 2000 et 2014 aux USA trié par ordre décroissant d’année d’apparition.
7. Donnez le nombre de film auquel à participé l’actrice Morgan entre 2000 et 2014.
8. Donnez les titres des films contenant Re (insensiblement à la casse).
9. Dans quels films Clint Eastwood est-il acteur mais pas réalisateur?
10. Donnez le résumé de spider man.
11. Quels films ont un résumé?
12. Quel sont les films qui ne sont ni des drames ni des comédies?
Mise-à-jour d’un document
Syntaxe:
db. <collection>.updateOne({. . . },{$set:{<champ>:<nouvelle valeur>}})
!Le premier paramètre de updateOne est un filtre utilisé pour chercher le
document a modifier. Si beaucoup de documents correspondent aux critères du
filtre; uniquement le premier document est modifié.
!Dans le deuxième paramètre; les champs à modifier sont spécifié avec leurs
nouvelles valeurs en utilisant l'operateur $set.
!$set met à jour le document qui correspond au filtre de sorte que les nouvelles
paires clés-valeurs apparaissent dans la nouvelle version du document.
!Si le champ spécifié à $set n'existe pas, le couple clé-valeur est ajouté au
document qui correspond au filtre.
Exemple
db. [Link]({title:"The
Martian"},{$set:{poster:"[Link] »}})
!Le champ poster n'existait pas dans le document dont le titre est "The
Martian", ce couple de clé-valeur sera ajouté au document en question.
Opérateurs de MAJ
!$set: remplace ou ajoute le champ spécifié.
!$unset: supprime le champ spécifié du document.
!$min: met a jour le champ si la valeur spécifié est plus petit que la valeur
existante.
!$max: met a jour le champ si la valeur spécifié est plus grande que la valeur
existante.
!$inc: incrémente la valeur du champ par la valeur specifié.
Il existe d'autres operateurs dans la documentation de MongoDB:
[Link]
Exemple
[Link]({title:"The
Martian"},{$inc:{"[Link]":3,"[Link]":25}})
!Le champ "[Link]" est incrémenté de 3
!Le champ "[Link]" est incrémenté de 25
Opérateurs de MAJ de tableaux
!$addToSet: Ajoute un élément à un tableau uniquement si cet élément n'existe pas déjà.
!$pop: Supprime soit le premier ou le dernier élément du tableau en fonction du paramètre de
$pop.
Syntaxe: { $pop: { <champ>: <-1 | 1>, ... } }
!$pullAll: Supprime tous les éléments d'un tableau qui vérifient une condition spécifiée en
paramètre.
{ $pullAll: { <champ>: [ <valeur1>, <valeur2> ... ], ... } }
!$push: Ajoute un élément à un tableau.
!$pushAll: Ajoute plusieurs éléments à un tableau.
Exemple 1
!Connectez vous localement à MongoDB avec la commande mongo.
!Insérez, dans la collection « movieScratch », le film suivant:
[Link]({ "_id" : ObjectId("5fb08ecd284503790637d12d"), "title" : "The
Martian", "year" : 2015, "rated" : "PG-13", "runtime" : 144, "countries" : [ "USA", "UK" ],
"genres" : [ "Adventure", "Drama", "Sci-Fi" ], "director" : "Ridley Scott", "writers" : [ "Drew
Goddard", "Andy Weir" ], "actors" : [ "Matt Damon", "Jessica Chastain", "Kristen Wiig", "Jeff
Daniels" ], "plot" : "During a manned mission to Mars, Astronaut Mark Watney is presumed dead
after a fierce storm and left behind by his crew. But Watney has survived and finds himself
stranded and alone on the hostile planet. With only meager supplies, he must draw upon his
ingenuity, wit and spirit to subsist and find a way to signal to Earth that he is alive.", "imdb" : {
"id" : "tt3659388", "rating" : 8.2, "votes" : 187881 }, "tomato" : { "meter" : 93, "image" :
"certified", "rating" : 7.9, "reviews" : 280, "fresh" : 261, "consensus" : "Smart, thrilling, and
surprisingly funny, The Martian offers a faithful adaptation of the bestselling book that brings out
the best in leading man Matt Damon and director Ridley Scott.", "userMeter" : 92, "userRating" :
4.3, "userReviews" : 104999 }, "metacritic" : 80, "type" : "movie" })
Exemple 1
db. [Link]({title:"The Martian"},{$push:{"reviews":{
rating:4.5,
date:ISODate("2016-01-12T09:00:00Z"),
reviewer:" Spencer H."}}})
!Le document de titre « The Martian » ne contient aucun champ nommé « reviews ».
!$push ajoute un nouveau champ nomme « reviews » au document dont le titre « The
Martian » .
!Le champs « reviews » est initialisé à une valeur spécifiée.
=> $push crée un tableau s'il n'existe pas.
Exemple 2
db. [Link]({title:"The Martian"},{$push:{"reviews":{
$each:[{rating:4.5,date:ISODate("2016-01-12T07:00:00Z"),reviewer:" Yabo A."},
{rating:5,date:ISODate("2016-01-12T09:00:00Z"),reviewer:" Kristina A."}]}}})
!Dans ce cas, $push ajoute chaque document au tableau valeur du champ « reviews ».
!Si $each n'est pas spécifié, tout le tableau sera inséré comme étant un seul élément au
tableau valeur du champ « reviews ».
db. [Link]({title:"The Martian"},{$pop:{"reviews":1}})
!Supprime le premier élément du tableau des « reviews ».
updateMany
! updateMany(): applique les mêmes modifications sur tous les documents qui correspondent au filtre.
! Exactement le même fonctionnement que la méthode updateOne(), sauf que les modifications sont
appliquées à tous les documents correspondants au filtre et non seulement le premier document.
Syntaxe:
db. <collection>.updateMany({.. . },{$set/$unset/. . . :{champ:<nouvelle_valeur>}})
Exemple:
db. [Link]({rated:null},{$unset: {rated:" "}})
! $unset: {rated:" "} : Supprime le champ « rated » des documents correspondants au filtre. La valeur " "
importe peu.
Upsert
!upsert: "update" +"replace"
!upsert met à jour les documents correspondants aux filtres; si aucun
document ne correspond au filtre alors un nouveau document est inséré
dans la collection.
Syntaxe:
!db. <collection>.updateMany({. . .
},{$set:{champ:<nouvelle_valeur>,{upsert:true})
Remplacer un document
!replaceOne(): est une extension des opérations CRUD utilisée soit pour
appliquer un filtre, insérer ou mettre a jour des données.
Syntaxe:
db. <collection>.replaceOne(<filtre>,<document de remplacement>)
!filtre: Spécifie le filtre utilisé pour sélectionner le document a remplacer
!document de remplacement: Le document qui remplacera celui
correspondant au filtre
!Si plusieurs documents correspondent au filtre, replaceOne() remplacera
uniquement le premier document.
Suppression de documents
!Supprimer un seul document: !Supprimer plusieurs documents:
Syntaxe: Syntaxe:
db. <collection>.deleteOne(<filtre>) db.<collection>.deleteMany(<filtre>)
Supprime le premier document Supprime tous les documents
correspondant au filtre. correspondants au filtre.
Exemple: Exemple:
[Link]({_id:Obje [Link]({"director
ctId("5fb08ecd284503790637d12d")} ":null})
)
Agrégation
!Le pipeline d’agrégation a une structure simple et fiable et une syntaxe qui se
répète.
!Les pipelines peuvent être composé d’une ou plusieurs étapes.
Syntaxe:
db. <collection>.aggregate([{Etape1},{Etape2},. . . ,{EtapeN}],{options})
!Chaque étape est un objet Json de paires clé-valeur.
!Nous pouvons avoir autant d’étapes que nous voulons (a part quelques
exceptions).
Agrégation
Transformations configurables:
• Expressions de filtre
• Transformation de données
• Calculs statistiques et analyse de données
Exemple
Utilisez la collection solarSystem de la base de données « Systems » pour tester les requêtes
d’agrégation.
[Link]([{
$match:{
meanTemperature:{$gte:-40,$lte:40}
}},{
$project:{_id:0,
name:1,
hasMoons:{$gt:["$numberOfMoons",0] }
}],
{allowDiskUse:true})
Exemple
! Une agrégation à 2 étapes: une étape $match et une étape $project.
! $project remodèle les documents sélectionnés par $match et calcule une nouvelle valeur « hasMoons ».
! aggregate, $match, $project: sont des operateurs d’agrégation.
! $in, $gte, $lte: sont des opérateurs d'interrogation (requête).
! Les étapes du Framework d’agrégation sont composées d’un ou plusieurs operateurs ou expressions.
! Les expressions peuvent prendre un seul argument ou un tableau d'arguments. Ceci dépend de
l'expression.
Exemple:
hasMoons:{$gt:["$numberOfMoons",0]}
! hasMoons:{$gt:["$numberOfMoons",0]} est une expression, ses arguments sont spécifié dans un
tableau.
! Les expressions apparaissent toujours dans une position de valeur.
Opérateurs de base
$match :
! doit être parmi les premières étapes du pipeline.
! utilise les operateurs d'interrogation standard de MongoDB (les filtres).
! filtre des documents selon un critère. $match peut être considéré comme un filtre pour remplacer find.
Le filtre est configuré dans l’étape $match et uniquement les documents vérifiant les critères sont passés
à la prochaine étape du pipeline.
Exemple:
Utilisez la base de données Systems:
[Link]([{$match:{type:{$ne:"Star"}}}])
! Equivalente à:
[Link]({type:{$ne:"Star"}})
Opérateurs de base
$project:
!est différente de la projection avec find; $project est beaucoup plus.
!ne se limite pas à la rétention ou suppression de champs; il permet aussi de réaffecter une
valeur de champ existant ou dériver entièrement un nouveau champ.
!applique des transformations sur les collections Mongo.
Syntaxe:
db. <collection>.aggregate([{$project:{<Expression_d’agrégation
ou Expression_logique>}}])
Exemple:
[Link]([{$project:{id:0,name:1,"[Link]":1}}])
$project
1. Avec $project, la valeur d'un champ existant peut être redirigée vers un autre champ.
Exemple:
[Link]([{$project:{
_id:0,
name:1,
gravity:"$[Link]"}}])
!Au lieu de renvoyer un sous-document avec la valeur du champ "[Link]", cette
valeur est directement affectée au champ "gravity".
!Affecter la valeur du champ "[Link]" ("$[Link]" ) au champ gravity.
$project
2. Avec $project, il est possible de créer un nouveau champ.
Exemple:
[Link]([{$project:{
id:0,
name:1,
surfaceGravity:"$[Link]"}}])
!surfaceGravity est nouveau champ qui vient d’être crée.
$project
3. Avec $project, il est possible de créer un nouveau champ calculé.
Exemple:
!"#$%&'.$#)*+
!Pour chaque planète, afficher le nom et un nouvel attribut nommé myWeight= ∗ 8.6
,.-
[Link]([{$project:{
id:0,
name:1,
myWeight:{$multiply:[
{$divide:["$[Link]",9.8]},86]}
}}])
$addFields
$addFields est très similaire a $project avec une différence clé.
!Comme son nom l'indique, $addFields ajoute des champs a un document.
Tandis qu'avec $project, des champs sont supprimés et/ou conservés de manière
sélective.
!$addFields permet uniquement de modifier les documents entrants au pipeline
en ajoutant de nouveaux champs calculés ou en modifiant des champs existants.
Exemple:


Combinaison $project et
$addFields
[Link]([{$project:{ [Link]([{$project:{
id:0, id:0,
name:1,
name:1,
gravity:1
mass:1, gravity:"$[Link]",
radius:1, mass:"$[Link]",
sma:1}}, radius:"$[Link]",
{$addFields:{gravity:"$[Link]", sma:"$[Link]"}}]).pretty()
mass:"$[Link]",
radius:"$[Link]",
sma:"$[Link]"}}
]).pretty()
Question: Comment choisir entre une utilisation unique de $project et une combinaison de
$project avec $addFields?
Les curseurs avec find
: retourne id, nom et
numberOfMoons de chaque document.
.skip(5).pretty(): saute les 5
premiers documents et retourne les 4 derniers. Les documents sont retournés selon leur ordre
d'insertion dans la collection.
.limit(5).pretty(): retourne les 5
premiers documents selon l'ordre naturel d'insertion.
.sort({numberOfMoons:-
1}).pretty(): au lieu de retourner les documents dans l'ordre d'insertion dans la collection, les
documents résultants sont triés par ordre décroissant du champ numberOfMoons.
Les curseurs dans un pipeline
Syntaxe:
! $limit:{<integer>}
! $skip:{<integer>}
! $count:{<nouveau champ contenant le nombre de documents>
! $sort:{<champ_du_tri>:<integer: sens du tri (1,-1)>}
Exemples:
! [Link]([{$project: {id:0,name:1,numberOfMoons:1}},{$limit:5}])
! [Link]([{$project: {id:0,name:1,numberOfMoons:1}},{$skip:1}])
! [Link]([{$match:{type:"Terrestrial
planet"},{$project:{id:0,name:1,numberOfMoons:1}},{$count:"terrestrial planets"}])
! [Link]([{$project:{id:0,name:1,numberOfMoons:1}},{$sort:{numberOfMoons:1}}])
! [Link]([{$project:{id:0,name:1,hasMagneticField:1,numberOfMoons:1}},{$sort:fhasMagneticFi
eld:-1,numberOfMoons:-1}}],{allowDiskUse:true})
Groupement des données
$group:
! Regroupe les documents de la collection par l'expression spécifiée dans l’_id.
! Pour chaque groupe distinct, $group génère un document.
! Le seul argument requis au $group est le _id. La ou les expressions spécifiées à l’_id sont les champs de
groupement.
! Le champ _id de chaque document de sortie contient une valeur unique par groupe.
Syntaxe:
db.<collection>.aggregate([{$group:{_id: <critère_de_groupement>,<Expression
d'accumulation>}]})
Exemple:
[Link]([{$group:{_id:"$year"}}])
Groupement des données
!Utiliser des expressions d'accumulation: les documents de sortie peuvent contenir des
champs calculés qui contiennent les valeurs d'une expression d'accumulation.
!Des champs supplémentaires (autant que nécessaire) peuvent être spécifiée afin
d’éffectuer des calculs dans la phase de groupement.
Exemples:



.
Groupement des données
!_id spécifie les critères de groupement des documents entrants;
!$group peut être utilise plusieurs fois dans un pipeline;
!Il peut être nécessaire de nettoyer les données entrantes à $group;
!Toutes les expressions d'accumulations peuvent être utilisées dans le groupement $group.
Expression d’accumulation:
!$sum: Renvoie une somme de valeurs numériques. Ignore les valeurs non numériques. Peut
être utilise dans $group et $project.
!$avg: Renvoie une moyenne de valeurs numériques. Ignore les valeurs non numériques. Peut
être utilisé dans $group et $project.
!$first: Renvoie une valeur du premier document pour chaque groupe. L'ordre n'est défini que si
les documents sont dans un ordre défini. Peut être utilise dans $group.
!$last: Renvoie une valeur du dernier document pour chaque groupe. L'ordre n'est défini que si
les documents sont dans un ordre défini. Peut être utilise dans $group.
Groupement des données
!$max: Renvoie la valeur d'expression la plus élevée pour chaque groupe. Peut être utilise dans
$group et $project.
!$min: Renvoie la valeur d'expression la plus faible pour chaque groupe. Peut être utilisé dans
$group et $project.
!$push: Renvoie un tableau de valeurs d'expression pour chaque groupe. Peut être utilisé dans
$group.
!$addToSet: Renvoie un tableau de valeurs d'expressions uniques pour chaque groupe. L'ordre
des éléments du tableau n'est pas défini. Peut être utilise dans $group.
!$stdDevPop: Renvoie l’écart type de population des valeurs d'entrée. Peut être utilisé dans
$group et $project.
!$stdDevSamp: Renvoie l’écart type d’échantillon des valeurs d'entrée. Peut être utilise dans
$group et $project.
Remarque: Les expressions de l'accumulations dans $project fonctionnent sur un tableau dans
les documents de la collection donnée.
Questions
Utilisez la collection « movieDetails » de la base de données « video » répondre aux
questions suivantes:
1. Quel est le nombre de film par ville?
2. Quel est le nombre de film par directeur?
3. Donnez l’année du film le plus ancien par ville.
4. Donnez l’année du film le plus récent par ville.
5. Donnez l’année du film le plus récent par ville. Triez le résultat par ordre décroissant
d’année.
6. Quel est le nombre de film par genre? triez le résultat par ordre décroissant de
nombre de film.
7. Quels sont les genres ayant plus de 10 films?
8. Donnez le nombre de films par genre et par ville.
$unwind
Exemple: le nombre de film par genre
[Link]([{$group:{_id:"$genres",nb_film:{$sum:1}}}])
Problème: le regroupement se fait sur des tableaux => Les tableaux
identiques sont regroupés
$unwind
!Opérateur d’agrégation sur les tableaux.
!Crée autant de documents que d’éléments dans le tableau: générer un
document pour chaque entrée du tableau.
Utilité: Regrouper des documents sur les valeurs distinctes d’un champ de
type tableau.
$unwind
Exemple: le nombre de film par genre:
[Link]([{$unwind:"$genres"},{$group:{_id:"$genres",n
b_film:{$sum:1}}}])
Question:
1. Donnez la moyenne de « [Link] » par année et par genre dans un
l’ordre décroissant des années et moyennes.
2. Ensuite, pour chaque année donnez le genre ayant la moyenne de
« [Link] » la plus forte. Triez le résultat par ordre décroissant
d’année.