systèmes de gestion de documents master informatique – 1ère...
TRANSCRIPT
11/11/2019
1
Module Systèmes de gestion de documents
CM2 : MongoDB – Interrogation des données
Insertion d'un document
Consultation des collections
Interrogation d'une collection
Indexation
Framework d'agrégation Les opérateurs d'agrégation
Exemples de requêtes d'agrégation avancées
Optimisation des "pipelines" d'agrégation
Le paradigme Map-Reduce
M1 Informatique - SGD - N. Cullot 1
CM2 : MongoDB – Insertion d'un document - Rappel
Plusieurs fonctionnalités sont disponibles pour insérer des documents insert, insertOne, insertMany
Il est possible d'insérer directement le document ou de le définir puis de l'insérer
document = ( { "Type" : "Livre", "Titre": "Guide to MongoDB", "ISBN" : "978-4-4842-1183-0", "Editeur" : "Apress", "Auteurs" : [ "David Hows", "Peter Membrey"]})
db.biblio.insertOne(document);
Résultat à l'exécution{
"acknowledged" : true,"insertedId" : ObjectId("5a113b98914f9051c79894a0")
}
La collection "biblio" est créée si elle n'existait pas déjà.
M1 Informatique - SGD - N. Cullot 2
11/11/2019
2
CM2 : MongoDB – Consultation des collections - Rappel
Visualisation des collections show collections
Affiche les noms des collections qui ont été créées
Visualisation de tous les documents d'une collection db.biblio.find();
{ "_id" : ObjectId("5a113b98914f9051c79894a0"), "Type" : "Livre", "Titre" : "Guide to MongoDB", "ISBN" : "978-4-4842-1183-0", "Editeur" : "Apress", "Auteurs" : [ "David Hows", "Peter Membrey" ] }
{ "_id" : ObjectId("5a113cf6914f9051c79894a1"), "Type" : "Livre", "Titre" : "BD NoSQL", "ISBN" : "978-2-212-14155-9", "Editeur" : "Eyrolles", "Auteurs" : [ "Rudi Bruchez" ] }
M1 Informatique - SGD - N. Cullot 3
CM2 : MongoDB – Interrogation d'une collection
Affichage des documents d'une collection selon un critère donné db.biblio.find({"Type":"Livre"});
Il est également possible de définir un critère (requête) et de spécifier la recherche query= ({"Type":"Livre"}); db.biblio.find(query);
Requête qui retourne tous les documents de type "Livre" avec la description complète du document
{ "_id" : ObjectId("5a113b98914f9051c79894a0"), "Type" : "Livre", "Titre" : "Guide to MongoDB", "ISBN" : "978-4-4842-1183-0", "Editeur" : "Apress", "Auteurs" : [ "David Hows", "Peter Membrey" ] }{ "_id" : ObjectId("5a113cf6914f9051c79894a1"), "Type" : "Livre", "Titre" : "BD NoSQL", "ISBN" : "978-2-212-14155-9", "Editeur" : "Eyrolles", "Auteurs" : [ "Rudi Bruchez" ] }
M1 Informatique - SGD - N. Cullot 4
11/11/2019
3
CM2 : MongoDB – Interrogation d'une collection
Filtrage des informations du document à afficher
Affichage du titre des livres uniquement (et l'identifiant) db.biblio.find({"Type":"Livre"}, {"Titre":1});
{ "_id" : ObjectId("5a113b98914f9051c79894a0"), "Titre" : "Guide to MongoDB" } { "_id" : ObjectId("5a113cf6914f9051c79894a1"), "Titre" : "BD NoSQL" }
Affichage du titre et de l'ISBN des livres (et l'identifiant) db.biblio.find({"Type":"Livre"}, {"Titre":1, "ISBN":1});
{ "_id" : ObjectId("5a113b98914f9051c79894a0"), "Titre" : "Guide to MongoDB", "ISBN" : "978-4-4842-1183-0" }
{ "_id" : ObjectId("5a113cf6914f9051c79894a1"), "Titre" : "BD NoSQL", "ISBN" : "978-2-212-14155-9" }
Affichage de toutes les informations sauf les auteurs db.biblio.find({"Type":"Livre"}, {"Auteurs": 0});
M1 Informatique - SGD - N. Cullot 5
CM2 : MongoDB – Interrogation d'une collection
Utilisation de la notation pointée Exemple de document avec des structures imbriquées
document = ( { "Type" : "CD", "Titre": "Nevermind", "Artiste" : "Nivarna", "Pistes" : [ {"Piste" :"1", Titre : "Teen Spirit"},{"Piste": "2", "Titre" : "In Bloom"}]})
db.biblio.insertOne(document);
Recherche sur le titre de la liste de pistes du CD db.biblio.find({"Pistes.Titre" : "In Bloom"});
Recherche dans un tableau de valeurs (simples) document = ( { "Type" : "Livre", "Titre": "Guide to MongoDB", "ISBN" : "978-4-4842-1183-
0", "Editeur" : "Apress", "Auteurs" : [ "David Hows", "Peter Membrey"]})
Recherche de tous les médias qui ont comme auteur David Hows. db.biblio.find({"Auteurs" : "David Hows"})
M1 Informatique - SGD - N. Cullot 6
11/11/2019
4
CM2 : MongoDB – Interrogation d'une collection
Utilisation des fonctions sort, limit, et skip sort : permet de trier une liste de résultats selon un critère de façon
croissante (valeur 1) ou décroissante (-1). db.biblio.find({"Type":"Livre"}, {"Titre":1}).sort({"Titre":1});
{ "_id" : ObjectId("5a116c55da9c61923d54c2be"), "Titre" : "BD NoSQL" }
{ "_id" : ObjectId("5a116c3fda9c61923d54c2bd"), "Titre" : "Guide to MongoDB" }
limit(n) : permet de ne retenir que les n premiers documents db.biblio.find({"Type":"Livre"}, {"Titre":1}).sort({"Titre":1}).limit(1);
{ "_id" : ObjectId("5a116c55da9c61923d54c2be"), "Titre" : "BD NoSQL" }
skip(n) : permet de "sauter" les n premiers documents db.biblio.find({"Type":"Livre"}, {"Titre":1}).sort({"Titre":1}).skip(1);
{ "_id" : ObjectId("5a116c3fda9c61923d54c2bd"), "Titre" : "Guide to MongoDB"
M1 Informatique - SGD - N. Cullot 7
CM2 : MongoDB – Interrogation d'une collection
Par défaut, la fonction sort, classe les documents sur le critère choisi, et selon un ordre "naturel" Par exemple ordre alphabétique sur les chaînes de caractères
Il est possible d'imposer que le tri reflète, non pas l'ordre par défaut, mais l'ordre d'insertion des documents Pour cela, il faut créer explicitement une collection ("capped collection"), en fixant
également sa taille à une taille maximum, et éventuellement un nombre maximum d'objets. Les anciennes valeurs sont supprimées si besoin (FIFO), Par exemple pour une collection de logs nommée "audit" db.createCollection ("audit", {capped:true, size: 20480, max:100})
{ "ok" : 1 }
Affichage des informations sur la collection créée : 10 premiers documents et par inverse de l'ordre d'insertion ($natural:-1) db.audit.find().sort({$natural: -1}).limit(10);
M1 Informatique - SGD - N. Cullot 8
11/11/2019
5
CM2 : MongoDB – Interrogation d'une collection
Utilisation des fonctionnalités d'agrégation : count, distinct, et group
count : donne le nombre de documents de la collection db.biblio.count()
db.biblio.find({"Type":"Livre"}).count();
distinct : permet d'obtenir des résultats sans doublons db.insertOne( { "Type" : "Livre", "Titre": "Guide to MongoDB", "ISBN" : "978-4-4842-1183-0",
"Editeur" : "Apress", "Auteurs" : [ "David Hows", "Peter Membrey"]})
db.biblio.insertOne( { "Type" : "Livre", "Titre": "Livre1", "ISBN" : "123456", "Editeur" : "Eyrolles"})
db.biblio.insertOne( { "Type" : "Livre", "Titre": "Livre2", "ISBN" : "345689", "Editeur" : "Eyrolles"})
db.biblio.distinct("Editeur");
Résultat [ "Apress", "Eyrolles" ]
M1 Informatique - SGD - N. Cullot 9
CM2 : MongoDB – Interrogation d'une collection
La fonction group permet de regrouper des résultats selon des critères donnés la fonction a 3 paramètres
key : qui indique les résultats à regrouper initial : 0 pour avoir le nombre exact de résultats
pour chaque groupe reduce : fonction qui prend 2 paramètres le
document en cours de traitement et l'agrégation (ici ajout de 1 au compteur)
db.biblio.group({ key : {Editeur:true},
initial: {Total :0},reduce : function(items, prev)
{ prev.Total+1;}})
M1 Informatique - SGD - N. Cullot 10
Résultat sur la collection biblio :[
{"Editeur" : "Apress","Total" : 1
},{
"Editeur" : "Eyrolles","Total" : 3
},{
"Editeur" : null,"Total" : 1
}]
11/11/2019
6
CM2 : MongoDB – Interrogation d'une collection
Utilisation des opérateurs de comparaison $gt (greater than), $gte (greater than equal), $lt, $lte
Exemple : db.personnes.insertOne({"nom":"Dupont", "age":32}) db.personnes.insertOne({"nom":"Durand", "age":45})
db.personnes.find({ age: {$gt : 35}}) Résultat
{ "_id" : ObjectId("5a119071b540c085a9c4d9fc"), "nom" : "Durand", "age" : 45 }
Recherche de tous les documents exceptés certains : $ne (not equal) db.personnes.find({"nom":{ $ne : "Dupont"}}) Résultat
{ "_id" : ObjectId("5a119071b540c085a9c4d9fc"), "nom" : "Durand", "age" : 45 }
M1 Informatique - SGD - N. Cullot 11
CM2 : MongoDB – Interrogation d'une collection
Utilisation d'un tableau de valeurs à chercher : $in, $nin Recherche des personnes ayant 32 ou 45 ans
db.personnes.find ( {"age" : {$in [32, 45]})
Recherche des personnes n'ayant ni 32 ans ni 45 ans db.personnes.find ( {"age" : {$nin [32, 45]})
Utilisation d'un opérateur logique $or ou $and Recherche des personnes ayant comme nom "Dupont" ou comme age 45 ans.
db.personnes.find ({ $or : [{"nom":"Dupont"}, {"age" : 45}]})
{ "_id" : ObjectId("5a118f89b540c085a9c4d9fb"), "nom" : "Dupont", "age" : 32 }
{ "_id" : ObjectId("5a119071b540c085a9c4d9fc"), "nom" : "Durand", "age" : 45 }
M1 Informatique - SGD - N. Cullot 12
11/11/2019
7
CM2 : MongoDB – Interrogation d'une collection Utilisation de l'opérateur $exist pour tester l'existence d'un champ spécifique
Recherche des documents n'ayant pas de liste de pistes (Pistes) db.biblio. find( { Pistes : {$exists : false}})
Retourne les médias autre que de type CD
{ "_id" : ObjectId("5a116c3fda9c61923d54c2bd"), "Type" : "Livre", "Titre" : "Guide to MongoDB", "ISBN" : "978-4-4842-1183-0", "Editeur" : "Apress", "Auteurs" : [ "David Hows", "Peter Membrey" ] }
...
Utilisation de l'opérateur $type, pour rechercher un champ d'un type BSON donné db.biblio.find ({ Pistes : {$type :3}}) -> 3 Embedded object db.personnes.find ({ age: {$type :16}}) -> Double
{ "_id" : ObjectId("5a118f89b540c085a9c4d9fb"), "nom" : "Dupont", "age" : 32 } { "_id" : ObjectId("5a119071b540c085a9c4d9fc"), "nom" : "Durand", "age" : 45 } { "_id" : ObjectId("5a119412b540c085a9c4d9fd"), "nom" : "Durand", "age" : 47 }
table qui donne les correspondances des types en BSON https://docs.mongodb.com/manual/reference/bson-types/
M1 Informatique - SGD - N. Cullot 13
CM2 : MongoDB – Interrogation d'une collection
Utilisation de l'opérateur $elemMatch pour s'assurer que deux champs ou plus répondent à certains critères en même temps
Recherche des médias ayant une piste avec un numéro et un titre donnés
document = ( { "Type" : "CD", "Titre": "Nevermind2", "Artiste" : "Nivarna", "Pistes" : [ {"Piste" :"4", Titre : "Teen Spirit"},{"Piste": "2", Titre : "In Bloom"}]})
db.biblio.insertOne(document);
db.biblio.find( { "Pistes" : { $elemMatch :{"Piste" : "1", "Titre" : "Teen Spirit"}}} ) Retourne uniquement le document ci-dessous avec Piste 1 et le titre souhaité
{ "_id" : ObjectId("5a116c7cda9c61923d54c2bf"), "Type" : "CD", "Titre" : "Nevermind", "Artiste" : "Nivarna", "Pistes" : [ { "Piste" : "1", "Titre" : "Teen Spirit" }, { "Piste" : "2", "Titre" : "In Bloom" } ] }
M1 Informatique - SGD - N. Cullot 14
11/11/2019
8
CM2 : MongoDB – Interrogation d'une collection
Utilisation de l'opérateur $not, qui retourne le complément de la requête décrite Attention : cela peut retourner un nombre important de documents
db.biblio.find( { "Pistes" : {$not :{ $elemMatch :{"Piste" : "1", "Titre" : "Teen Spirit"}}} })
Retourne tous les médias, qui n'ont pas à la fois une piste de numéro 1 et du titre souhaité.
Utilisation d'expressions régulières Recherche des documents ayant un titre commençant par "bd", de façon non
sensible à la casse db.biblio.find( {"Titre" : /^bd/i})
{ "_id" : ObjectId("5a116c55da9c61923d54c2be"), "Type" : "Livre", "Titre" : "BD NoSQL", "ISBN" : "978-2-212-14155-9", "Editeur" : "Eyrolles", "Auteurs" : [ "Rudi Bruchez" ] }
M1 Informatique - SGD - N. Cullot 15
CM2 : MongoDB – Interrogation d'une collection
Autres formes de requêtes Les requêtes peuvent se baser sur des expressions écrites en javascript
Avantage : forme plus flexible avec plus de fonctions
Inconvénient : ne tire pas avantage des index gérés dans les formes de requêtes natives de MongoDB
Les formes suivantes permettent de rechercher des personnes de plus de 25 ans db.personnes.find({ age: {$gt : 25}}) -- forme native
db.personnes.find( { $where: "this.age > 25"})
db.personnes.find( "this.age > 25")
f= function () { return this.age > 25}
db.personnes.find(f);
M1 Informatique - SGD - N. Cullot 16
11/11/2019
9
CM2 : MongoDB – Gestion des index Un index est une structure qui comporte de l'information
Pour les valeurs de champs spécifiques d'un document d'une collection
L'index permet une recherche rapide des données des documents
On peut considérer un index comme une pseudo requête qui a été exécutée et dont les résultats ont été stockés
Créer des index spécifiques sur des données requêtées de façon intensive, Accroît considérablement les temps d'exécution des requêtes
Créer des index est en pratique, assez simple mais il est aussi nécessaire de les supprimer, les reconstruire, etc.
Il existe différents types d’index (simple, composé, multiclé, 2dSphere, 2d, …)
M1 Informatique - SGD - N. Cullot 17
CM2 : MongoDB – Gestion des index
La création d'un index nécessite au minimum le nom d'un champ/clé du document Index sur la champ "Titre" du document
db.biblio.createIndex( {"Titre" :1}) La valeur 1 indique que les entrées de l'index seront en ordre croissant, -1 pour décroissant
Index sur le titre d'une piste dans le tableau des pistes (pour un CD) db.biblio.createIndex( {"Pistes.Titre" :1})
Il est aussi possible de créer un index sur plusieurs champs, Index sur le titre et l’artiste
db.biblio.createIndex( {"Titre" :1, "Artiste" :1}
Index sur la piste et le titre des pistes db.biblio.createIndex( { "Pistes.Piste" :1, "Pistes.Titre" :1})
Depuis sa version 1.4 MongoDB propose une implémentation d'un index géospatial Dédié aux requêtes qui gèrent des géo-localisations
db.restaurants.insert({"nom" : "Kyriad", loc: { type: "Point", coordinates: [52.370451, 5.217497]}}) db.restaurants.ensureIndex({loc: "2dsphere"});
M1 Informatique - SGD - N. Cullot 18
11/11/2019
10
CM2 : MongoDB – Gestion des index
Il est possible
Lister tous les index d ’une collection (biblio) db.biblio.getIndexes()
Supprimer un index spécifique db.biblio.dropIndex( {"Pistes.Titre" :1})
Supprimer tous les index d’une collection db.biblio.dropIndexes()
Un index ne peut pas être modifié (sauf certains types d’index spécifiques),
Il doit être supprimé puis récrée
M1 Informatique - SGD - N. Cullot 19
CM2 : MongoDB – Framework d'agrégation
Depuis la version 2.2, MongoDB propose
un framework d'agrégation (aggregation framework) pour réaliser des opérations complexes d'analyse
qui permet de récupérer et manipuler les données dans mongoDB,
Sans utiliser des traitements complexes en batch avec Map/Reduce
Il fournit des opérateurs comme $group, $limit, $match, $sort, $unwind, $project, $skip, $out, $redact, $ lookup, etc.
https://docs.mongodb.com/manual/reference/operator/aggregation/index.html
Pour regrouper les données et les manipuler en créant un "pipeline" d'agrégation
db.collection.aggregate( [ { … }, { …}, ... ] ) https://docs.mongodb.com/manual/aggregation/
M1 Informatique - SGD - N. Cullot 20
11/11/2019
11
CM2 : MongoDB – Framework d'agrégationRequêtes avancées
Le framework d'agrégation comporte un ensemble large d'opérateurs, Qui permet de manipuler les
collections, de les filtrer, les remettre en forme, les restreindre, etc.
En travaillant sous forme d'un pipeline de collections de documents
Une requête d'agrégation est de la forme db.collection.aggregate( [{…},{…}, …])
M1 Informatique - SGD - N. Cullot 21
https://docs.mongodb.com/manual/core/aggregation-pipeline/#pipeline
CM2 : MongoDB – Framework d'agrégationLes opérateurs d'agrégation
L'opérateur $group permet de regrouper les entrées d'un document, selon une expression donnée, d'effectuer des cumuls si besoin
Exemple : collection "tests"{ "_id" : 1, "item" : "abc", "prix" : 10, "quantite" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }
Regroupement par mois, jour et année, et calcul du prix total et des quantités moyennes db.tests.aggregate( [
{ $group : { _id : { mois: { $month: "$date" }, jour: { $dayOfMonth: "$date" }, an: { $year: "$date" } }, PrixTotal: { $sum: { $multiply: [ "$prix", "$quantite" ] } }, QuantiteMoyenne: { $avg: "$quantite" }, NombreObjets: { $sum: 1 } } }
])
M1 Informatique - SGD - N. Cullot 22
11/11/2019
12
CM2 : MongoDB – Framework d'agrégationLes opérateurs d'agrégation
Collection db.tests.insertOne({ "_id" : 1, "item" : "abc", "prix" : 10, "quantite" : 2, "date" : ISODate("2014-03-
01T08:00:00Z") })
db.tests.insertOne({ "_id" : 2, "item" : "abc", "prix" : 10, "quantite" : 2, "date" : ISODate("2014-03-01T08:00:00Z") })
db.tests.insertOne({ "_id" : 3, "item" : "abc", "prix" : 10, "quantite" : 2, "date" : ISODate("2015-03-01T08:00:00Z") })
Résultat { "_id" : { "mois" : 3, "jour" : 1, "an" : 2015 }, "PrixTotal" : 20, "QuantiteMoyenne" : 2, "
NombreObjets " : 1 }
{ "_id" : { "mois" : 3, "jour" : 1, "an" : 2014 }, "PrixTotal" : 40, "QuantiteMoyenne" : 2, " NombreObjets " : 2 }
M1 Informatique - SGD - N. Cullot 23
CM2 : MongoDB – Framework d'agrégationLes opérateurs d'agrégation
L'opérateur $limit, limite le nombre de documents pour la suite de la séquence de traitement db.tests.aggregate( { $limit : 5 } );
Pas d'effet sur les documents passés
L'opérateur $skip, permet de "sauter" n documents pour la suite de la séquence de traitement, et transmet le reste des documents db.tests.aggregate( { $skip: 3 } );
L'opérateur $match, permet de filtrer des documents à passer au pipeline, selon une ou des conditions db.tests.aggregate( [ { $match : { auteur : "Dupont" } } ] );
db.tests.aggregate( [ { $match: { $or: [ { score: { $gt: 70, $lt: 90 } }, { views: { $gte: 1000 } } ] } }] );
M1 Informatique - SGD - N. Cullot 24
11/11/2019
13
CM2 : MongoDB – Framework d'agrégationLes opérateurs d'agrégation
L'opérateur $sort, trie les documents et les transmet de façon ordonnée au pipeline db.tests.aggregate( [ { $sort : { age : -1 } }] )
1 = ordre croissant, -1 décroissant
L'opérateur $project, permet de mettre en forme les documents avec les champs existants ou de nouveaux champs, avant de les passer au pipeline
{ "_id" : 1, titre: "abc123", "isbn": "0001122223334", "auteurs": { last: "zzz", first: "aaa" }, "copies": 5 }
db.tests.aggregate( [ { $project : { titre : 1 , auteurs : 1 } } ] ) { "_id" : 1, "titre" : "abc123", "auteurs" : { "last" : "zzz", "first" : "aaa" } }
M1 Informatique - SGD - N. Cullot 25
CM2 : MongoDB – Framework d'agrégationLes opérateurs d'agrégation
L'opérateur $unwind permet de réorganiser les champs d'un tableau, avec un document pour chaque élément du tableau Exemple de document
{ "_id" : 1, "article" : "ABC1", "tailles": [ "S", "M", "L"] }
Restructuration db.tests.aggregate( [ { $unwind : "$tailles" } ] )
db.tests.aggregate( [ { $unwind: { path: "$tailles" } } ] ) – autre forme possible
Résultats { "_id" : 1, "article" : "ABC1", "tailles" : "S" }
{ "_id" : 1, "article" : "ABC1", "tailles" : "M" }
{ "_id" : 1, "article" : "ABC1", "tailles" : "L" }
M1 Informatique - SGD - N. Cullot 26
11/11/2019
14
CM2 : MongoDB – Framework d'agrégationLes opérateurs d'agrégation
L'opérateur $out permet de créer une collection avec le résultat d'un pipeline Exemple de documents d'une collection "Livres"
{ "_id" : 8751, "titre" : "The Banquet", "auteur" : "Dante", "copies" : 2 }
{ "_id" : 8752, "titre" : "Divine Comedy", "auteur" : "Dante", "copies" : 1 }
Regroupement des titres pour un auteur, et création d'une collection "Auteurs" db.livres.aggregate( [ { $group : { _id : "$auteur", "livres": { $push: "$titre" } } }, { $out : "authors" } ]
)
le $push permet de regrouper les informations des titres dans un tableau
Résultat: collection "Auteurs" { "_id" : "Dante", "livres" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
M1 Informatique - SGD - N. Cullot 27
CM2 : MongoDB – Framework d'agrégationLes opérateurs d'agrégation
L'opérateur $lookup, permet de faire une "jointure" entre des objets de deux collections, Exemple
Collection articles { "_id" : 1, "article" : "abc", "prix" : 12, "quantite" : 2 }
Collection inventaire { "_id" : 1, "unite" : "abc", description: "produit1", "stock" : 120 }
db.articles.aggregate([ { $lookup: { from: "inventaire", localField: "article", foreignField: "unite", as: "inventaire_docs" } } ])
Résultat { "_id" : 1, "article" : "abc", "prix" : 12, "quantite" : 2, "inventaire_docs" : [ { "_id" : 1, "unité" :
"abc", description: "produit 1", "stock" : 120 } ] }
M1 Informatique - SGD - N. Cullot 28
11/11/2019
15
CM2 : MongoDB – Framework d'agrégationRequêtes avancées
Exemple de document { "_id": "21000", "Ville": "DIJON", "Region": "Bourgogne", "Population":
15000, "gps": [47.316667, 5.016667 ] }
Recherche des régions dont la population est supérieure à 1 million db.villes.aggregate( [ { $group: { _id: "$Region", totalPop: { $sum:
"$population" } } }, { $match: { totalPop: { $gte: 1000*1000 } } } ] )
$group regroupe les documents selon la région, calcule le total de la population (avec $sum)
et fournit un document unique pour chaque région
$match filtre les documents dont la valeur de la population totale est supérieure à 1000000.
M1 Informatique - SGD - N. Cullot 29
CM2 : MongoDB – Framework d'agrégationRequêtes avancées Exemple de document
{ "_id": "21000", "Ville": "DIJON", "Region": "Bourgogne", "Population": 150000, "gps": [47.316667, 5.016667 ] }
{ "_id": "21000", "Ville": "BEAUNE", "Region": "Bourgogne", "Population": 60000 }
Recherche la moyenne de la population des villes par régiondb.villes.aggregate( [
{ $group: { _id: { Region: "$Region", Ville: "$Ville" }, pop: { $sum: "$Population" } } },{ $group: { _id: "$_id.Region", avgVillePop: { $avg: "$pop" } } }
] ) Le 1er $group regroupe les documents selon la région et la ville et calcule la population
pour chaque combinaison { "_id" : { "Region" : "Bourgogne", "Ville" : "DIJON" }, "pop" : 150000 }
Le 2ème $group calcule la moyenne par région
Résultat { "_id" : "Bourgogne", "avgVillePop" : 105000 }
M1 Informatique - SGD - N. Cullot 30
11/11/2019
16
CM2 : MongoDB – Framework d'agrégationRequêtes avancées Exemple de document
{ "_id": "21000", "Ville": "DIJON", "Region": "Bourgogne", "Population": 150000, "gps": [47.316667, 5.016667 ] } { "_id": "21000", "Ville": "BEAUNE", "Region": "Bourgogne", "Population": 60000 }
Recherche des villes les plus petite et plus grande d'une régiondb.villes.aggregate( [
{ $group: {_id: { Region: "$Region", Ville: "$Ville" },Population: { $sum: "$Population" }
} },{ $sort: { Population: 1 } },{ $group: {
_id : "$_id.Region",VilleLaPlusGrande: { $last: "$_id.Ville" },PopulationLaPlusGrande: { $last: "$Population" },VilleLaPlusPetite: { $first: "$_id.Ville" },PopulationLaplusPetite: { $first: "$Population" }
} },{ $project: { _id: 0,Region: "$_id",VilleLaPlusGrande: { nom: "$VilleLaPlusGrande", PopulationLaPlusGrande: "$PopulationLaPlusGrande" },VilleLaPlusPetite: { nom: "$VilleLaPlusPetite", PopulationLaPlusPetite: "$PopulationLaPlusPetite" }
} } ] )
M1 Informatique - SGD - N. Cullot 31
Population par ville et par région
Tri ordre croissant
Dernière et 1ère
villes
Construction du document réponse
CM2 : MongoDB – Framework d'agrégationRequêtes avancées
Résultat de la requête
{ "VilleLaPlusGrande" : { "nom" : "DIJON", "PopulationLaPlusGrande" : 150000 },
"VilleLaPlusPetite" : { "nom" : "BEAUNE", "PopulationLaPlusPetite" : 60000 },
"Region" : "Bourgogne"
}
M1 Informatique - SGD - N. Cullot 32
11/11/2019
17
CM2 : MongoDB – Framework d'agrégationOptimisation des "pipelines"
Les opérations d'agrégation sont sujettes à une phase d'optimisation Pour réorganiser les pipelines pour améliorer les performances
Les séquences d'instructions comme : $sort + $match, $skip + $limit, $redact +$match,
etc.
Peuvent être réorganisées automatiquement pour améliorer les performances
M1 Informatique - SGD - N. Cullot 33
CM2 : MongoDB – Framework d'agrégationOptimisation des "pipelines"
Optimisation de la séquence $sort + $match Lorsque qu'une séquence comporte
un $sort (tri) suivi d'un $match (filtre)
Le $match est déplacé avant le $sort
Exemple {$sort: {age:-1}} , {$match: { etat: "A"}}
Devient
{$match: { etat: "A"}}, {$sort: {age:-1}}
Cela permet de minimiser le nombre d'objets à trier.
M1 Informatique - SGD - N. Cullot 34
11/11/2019
18
CM2 : MongoDB – Framework d'agrégationOptimisation des "pipelines"
Optimisation de la séquence $skip + $limit Lorsque qu'une séquence comporte
un $skip (passer) suivi d'un $limit (limiter)
Le $skip est déplacé avant le $limit, la valeur de la limite est incrémentée avec la valeur du skip
Exemple {$skip: 10}, {$limit : 5}
Devient
{$limit: 15}, {$skip: 10}
Cela permet de limiter tout de suite le nombre d'objets à manipuler
M1 Informatique - SGD - N. Cullot 35
CM2 : MongoDB – Framework d'agrégationOptimisation des "pipelines"
Optimisation de la séquence $project + $skip ou $limit Lorsque qu'une séquence comporte
un $project (projeter) suivi d'un $skip (passer) ou d'un $limit (limiter)
Le $limit ou le $skip est déplacé avant le $project,
Exemple {$sort: {age:1}} {$project: { {etat:1 , nom:1}} {$limit: 5}
Devient
{$sort: {age:1}} {$limit: 5} {$project: { {etat:1 , nom:1}}
Cela permet de limiter plus tôt le nombre d'objets à manipuler
M1 Informatique - SGD - N. Cullot 36
11/11/2019
19
CM2 : MongoDB – Framework d'agrégationOptimisation des "pipelines"
Optimisation de la séquence $sort + $limit Lorsque qu'une séquence comporte
un $sort (trier) suivi d'un $limit (limiter)
L'optimiseur "fusionne" la contrainte de limite dans le tri.
Cela permet de ne gérer que les n premiers résultats pendant le tri Et seulement n objets sont stockés en mémoire
Optimisation de la séquence $limit +$limit Les deux limites sont fusionnées en une seule
{$limit:100}, {$limit:10} devient {$limit:10}
Optimisation de la séquence $skip +$skip Les deux sauts sont fusionnés en un seul
{$skip:5}, {$skip:2} devient {$skip:7}
M1 Informatique - SGD - N. Cullot 37
CM2 : MongoDB – Framework d'agrégationOptimisation des "pipelines"
Optimisation de la séquence $match +$match
Les deux conditions sont fusionnées en une seule {$match: {annee: 2017}, {$match:{etat: "A"} }
devient {$match : { $and [{annee: 2017}, {etat: "A"}] }}
Optimisation de la séquence $lookup +$unwind
Les deux opérateurs sont fusionnés pour éviter les création de grands documents intermédiaires { $lookup: { from: "autreCollection", as: "ResultatArray", ChampLocal: "x", ChampAutre:
"y" } }, { $unwind: "$ResultatArray"}
devient en interne
{ $lookup: { from: "autreCollection", as: "ResultatArray", ChampLocal: "x", ChampAutre: "y" , unwinding: {preserveNullAndEmptyArrays: false}}
D'autres combinaisons d'opérateurs sont également optimisées
M1 Informatique - SGD - N. Cullot 38
11/11/2019
20
CM2 MongoDB - Le paradigme MapReduce
D'une façon générale, le paradigme MapReduce est une approche de traitement distribué de l'information Qui prend une liste en entrée,
Et en produit une en retour.
MapReduce a été défini en 2004 dans un article rédigé par Google.
Google a proposé pour distribuer un traitement, une opération en deux étapes Une distribution des opérations sur chaque machine (Map)
Suivie après traitement, d'un rassemblement des résultats (Reduce)
M1 Informatique - SGD - N. Cullot 39
CM2 : Requêtes avancéesLe paradigme MapReduce
Le paradigme MapReduce offre des solutions pour répondre ou contourner les difficultés liées au traitement distribué
comme La défaillance d'une unité de traitement La bonne répartition du travail La synchronisation efficace et pertinente des résultats
MapReduce est né du besoin de Google de Traiter de très grands volumes de données déstructurées comme
Pages web pour des moteurs de recherche Des logs produits par le travail des moteurs d'indexation
Pour en tirer des résultats Calculs, Agrégats, résumés, etc.
Pour réaliser de l'analyse.
M1 Informatique - SGD - N. Cullot 40
11/11/2019
21
CM2 : Requêtes avancéesLe paradigme MapReduce
La réduction des coûts matériels a ouvert la voie à des solutions logicielles avec des environnements distribués Pour répondre à des montées en charge importantes du volume des données
à traiter
L'optimisation des performances d'un système de gestion de données sur une seule machine Demande beaucoup d'énergie et de compétences
Pour des solutions souvent fragiles et pas nécessairement stables à la charge
La spécification d'un modèle de données bien adapté pour un traitement distribué sur plusieurs machines Est une bonne réponse à la montée en charge pour la gestion de données
massives
M1 Informatique - SGD - N. Cullot 41
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
MapReduce est un des mécanismes les plus complexes de requêtes de mongoDB
Il se base sur la spécification des deux fonctions Map et Reduce (en javascript)
Ces deux fonctions sont des fonctions définies par l'utilisateur.
En mongoDB, La fonction Map, permet de générer des documents clés-valeurs pour les
transmettre en entrée à Reduce. La fonction Reduce retourne le résultat agrégé à partir de ces documents en
entrée. Une fonction optionnelle Finalize peut terminer le traitement pour une
meilleure présentation ou pour réaliser des calculs complémentaires
M1 Informatique - SGD - N. Cullot 42
11/11/2019
22
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
Exemple de requêtes MapReduce
On considère une collection de documents "villes", de la formedb.villes.insertOne ({ "_id": "21000", "Ville": "DIJON", "Region": "Bourgogne", "Population": 150000, "gps": [47.316667, 5.016667 ] } );
db.villes.insertOne ({ "_id": "21200", "Ville": "BEAUNE", "Region": "Bourgogne", "Population": 22000 });
Etc.
On souhaite calculer la population totale par région Les données pourraient être distribuées sur plusieurs serveurs
Un document de type clé-valeur est construit par la fonction Map
Ce document est utilisé en entrée par la fonction Reduce
M1 Informatique - SGD - N. Cullot 43
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
1er exemple var map=function(){ emit(this.Region, this.Population);}
La fonction Map, crée un document avec comme clé la région et la population comme valeur
Ce document est transmis à la fonction reduce
var reduce = function (region, pop) { }; La fonction Reduce ne fait rien dans cet exemple pour bien montrer que la valeur de
sortie sera nulle et que la région est la clé du document
db.villes.mapReduce(map,reduce, {out: { inline :1}}); Exécution des fonctions Map et Reduce, sur la collection des villes et affichage des
résultats
M1 Informatique - SGD - N. Cullot 44
11/11/2019
23
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
1er exemple : Résultats
Nombre de documents en entrée : 4
émis (vers reduce) : 4
après la fonction reduce 2
en sortie 2
La région est une clé (unique)
La valeur est null, pas de traitement par la fonction Reduce
M1 Informatique - SGD - N. Cullot 45
"results" : [{ "_id" : "Bourgogne",
"value" : null},{"_id" : "Fanche-Comte",
"value" : null}
],"timeMillis" : 26,"counts" : {
"input" : 4,"emit" : 4,"reduce" : 2,"output" : 2
},"ok" : 1
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
2ème exemple : on complète la fonction Reduce var map=function(){ emit(this.Region, this.Population);}
La fonction Map, crée un document avec comme clé la région et la population comme valeur
Ce document est transmis à la fonction reduce
var reduce = function(region, pop) { return Array.sum(pop);} La fonction Reduce calcule la somme des populations d'une région
db.villes.mapReduce(map,reduce, {out: { inline :1}}); Exécution des fonctions Map et Reduce, sur la collection des villes et affichage des
résultats
M1 Informatique - SGD - N. Cullot 46
11/11/2019
24
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
2ème exemple : Résultats
Nombre de documents en entrée : 4
émis (vers reduce) : 4
après la fonction reduce 2
en sortie 2
La région est une clé (unique)
La valeur est la somme des population des villes par région
M1 Informatique - SGD - N. Cullot 47
"results" : [{ "_id" : "Bourgogne",
"value" : 172000},{ "_id" : "Fanche-Comte",
"value" : 150000}
],"timeMillis" : 26,"counts" : {
"input" : 4,"emit" : 4,"reduce" : 2,"output" : 2
},"ok" : 1
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
3ème exemple : Calcul de la moyenne des populations par région1ère étape : fonction Map
var map =function(){
var value = {pop: this.Population, count:1};
emit(this.Region, value);
}
La fonction Map, crée un document avec comme clé la région et comme valeur une structure avec deux champs (pop, et count) La valeur de la pop est la région
La valeur de count est 1 (pour compter et ensuite calculer la moyenne)
Ce document est transmis à la fonction reduce
M1 Informatique - SGD - N. Cullot 48
11/11/2019
25
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
3ème exemple : Calcul des sommes des populations par région et du nombre de villes
2ème étape : fonction Reducevar reduce = function(region, val)
{ reduceValue = { pop:0, count:0}; for (var i=0; i<val.length;i++) {
reduceValue.pop += val[i].pop; reduceValue.count += val[i].count;
} return reduceValue; };
La fonction Reduce, crée un document clé/valeur avec comme clé la région (_id) et comme valeur une structure avec deux champs pop qui contient le total de la population de la région, et count qui indique le nombre de villes (ici documents traités).
M1 Informatique - SGD - N. Cullot 49
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
3ème exemple db.villes.mapReduce(map,reduce,
{out: { inline :1}}); Exécution des fonctions Map et Reduce,
sur la collection des villes et affichage des résultats
Nombre de documents en entrée : 4 émis (vers reduce) : 4 après la fonction reduce 2 en sortie 2
La région est une clé (unique) La valeur contient la somme des
population des villes par région, et le nombre de villes par région
M1 Informatique - SGD - N. Cullot 50
"results" : [{ "_id" : "Bourgogne",
"value" : {"pop" : 172000,"count" : 2
}},{ "_id" : "Fanche-Comte",
"value" : {"pop" : 150000,"count" : 2
}}
],"timeMillis" : 27,"counts" : {
"input" : 4,"emit" : 4,"reduce" : 2,"output" : 2
},"ok" : 1
11/11/2019
26
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
Le résultat peut être affiché db.villes.mapReduce(map,reduce, {out: { inline :1}});
Il peut aussi être stocké dans une autre collection
db.villes.mapReduce(map,reduce, {out: "collectionResult"});
db.collectionResult.find();
M1 Informatique - SGD - N. Cullot 51
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
Pour le 3ème exemple, le calcul des moyennes des populations par région, peut être réalisé par une fonction "finalize" qui effectue le traitement
La fonction "finalize" prend en entrée, le document produit par la fonction reduce.
var finalize = function (key, value) { value.avg= value.pop/value.count;
return value;}
Exécution des fonctions Map et Reduce, et Finalize sur la collection des villes db.villes.mapReduce(map,reduce, {out: { inline :1}, finalize:finalize});
M1 Informatique - SGD - N. Cullot 52
11/11/2019
27
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
3ème exemple (avec finalize) en entrée : 4
émis (vers reduce) : 4
après la fonction reduce 2
en sortie 2
La région est une clé (unique)
La valeur comporte la population totale de la région, le nombre de villes et la moyenne de population par ville
M1 Informatique - SGD - N. Cullot 53
{"results" : [
{ "_id" : "Bourgogne","value" : {
"pop" : 172000,"count" : 2,"avg" : 86000
}},{ "_id" : "Fanche-Comte",
"value" : {"pop" : 150000,"count" : 2,"avg" : 75000
}}
],"timeMillis" : 26,"counts" : {
"input" : 4,"emit" : 4,"reduce" : 2,"output" : 2
},"ok" : 1
CM2 : Requêtes avancéesLe paradigme MapReduce en MongoDB
Le paradigme de MapReduce permet de créer des documents de type clé-valeur à partir de collections
(fonction Map) Qui peuvent être distribuées
et de traiter ces documents (fonction Reduce) pour créer d'autres documents clé-valeur résultats
La méthode Finalize permet de compléter les traitements si besoin
Ce paradigme permet de traiter des requêtes complexes sur des données massives Grand volume de données et le cas échéant des données distribuées
M1 Informatique - SGD - N. Cullot 54