🖨️ Version PDF
Revoir l’énoncé si besoin
lesavions
Avec Mongo, on gère des collections qui contiennent des documents. Dans notre TP, nous avons 3 fichiers JSON structurés pour une base de données relationnelle. Nous devons raisonner différemment car les requêtes seront exécutées sur des documents appartenant à une seule Collection.
Mais comment créer une structure de document qui reprend les attributs des 3 fichiers JSON Avion, Pilote et Vol ?
En fait, il y a plusieurs solutions possibles, on pourrait prendre la structure du fichier JSON VOL puisque nous avons un Vol associé à un et un seul Pilote et forcément un et un seul Avion. Cependant, certaines requêtes seraient plus compliquées en NoSQL si l’on souhaite faire des recherches sur les Avions !
Donc la solution la plus serait de prendre la structure de départ du fichier JSON Avion et d’y greffer un tableau de Vol qui forcément est associé à un pilote ! Il pourrait y avoir des tableaux Vols vides pour un avion qui ne volent pas. Par contre, que fait-on des Pilotes qui ne volent pas ? Je vous laisseméditer…
Ce choix ci-dessosu, n’est pas forcément le meilleur mais il sera plus évident pour rédiger nos requêtes en NoSQL !
Structure d’un document de notre Collection lesavions :
{ "_id": 100, "constructeur": "AIRBUS", "modele": "A320", "capacite": 300, "site": "NICE", "vols": [ { "vol_id": "IT100", "site_depart": "NICE", "site_arrivee": "PARIS", "heure_depart": "07:00", "heure_arrivee": "09:00", "pilote": { "id": 1, "nom": "DORE", "site": "NICE" } } ] }
Inconvénients : Mais où sont les pilotes qui ne volent pas ?
Un pilote qui ne vole pas n’apparaît nulle part, on perd l’information et c’est un problème de modélisation orientée documents !
Il existe des solutions comme la possibilité d’ajouter un tableau pilotes au niveau racine de la collection, mais c’est pas l’idéal, sinon, il vaut mieux créer une collection à part pour tous les pilotes, même ceux qui ne volent pas… cependant, ce n’est pas l’objectif de ce tp.
Exemple :
{ "_id": "pilotes", "pilotes": [ { "id": 1, "nom": "DORE", "prenom": "Julien", "site": "NICE" }, { "id": 2, "nom": "JORDANA", "prenom": "Camélia", "site": "PARIS" }, { "id": 5, "nom": "DUPONT", "site": "LYON" } ] }
Du coup, les pilotes existent même sans vol et les vols font référence à un pilote via son identifiant du pilote (pilote_id). C’est une solution.
{ vol_id: "IT100", pilote_id: 1 } >En NoSQL, **on modélise les données selon les usages et non selon les entités** comme dans un MCD. ## Création de la base MongoDB >Le `use` permet de créer la base automatiquement. Vous pouvez la nommer comme vous voulez ! ```js use bd_avions
db.createCollection("lesavions")
On va utiliser insertMany()
insertMany()
db.lesavions.insertMany([ { _id:100, constructeur:"AIRBUS", modele:"A320", capacite:300, site:"NICE" }, { _id:101, constructeur:"BOEING", modele:"B707", capacite:250, site:"PARIS" }, { _id:102, constructeur:"AIRBUS", modele:"A320", capacite:300, site:"TOULOUSE" }, { _id:103, constructeur:"CARAVELLE", modele:"Caravelle", capacite:200, site:"TOULOUSE" }, { _id:104, constructeur:"BOEING", modele:"B747", capacite:400, site:"PARIS" }, { _id:105, constructeur:"AIRBUS", modele:"A320", capacite:300, site:"GRENOBLE" }, { _id:106, constructeur:"ATR", modele:"ATR42", capacite:50, site:"PARIS" }, { _id:107, constructeur:"BOEING", modele:"B727", capacite:300, site:"LYON" }, { _id:108, constructeur:"BOEING", modele:"B727", capacite:300, site:"NANTES" }, { _id:109, constructeur:"AIRBUS", modele:"A340", capacite:350, site:"BASTIA" } ])
On peut compter le nombre documents ajoutés.
db.lesavions.countDocuments()
Tout simplement les afficher.
db.lesavions.find().pretty()
db.lesavions.find({}, {_id:1})
ou ça si vous voulez plus d’infos :
db.lesavions.find({}, {_id:1, constructeur:1, modele:1})
db.lesavions.distinct("vols.pilote.nom")
Si on souhaite afficher les prénoms des pilotes, on est obligé de faire un aggregate comme ceci :
aggregate
Avec Doublons :(
db.lesavions.aggregate([ { $unwind: "$vols" }, { $project: { _id: 0, nom: "$vols.pilote.nom", prenom: "$vols.pilote.prenom" } } ])
et sans doublons :
db.lesavions.aggregate([ { $unwind: "$vols" }, { $group: { _id: { nom: "$vols.pilote.nom", prenom: "$vols.pilote.prenom" } } }, { $project: { _id: 0, nom: "$_id.nom", prenom: "$_id.prenom" } } ])
db.lesavions.distinct("constructeur")
plus complexe ici, il faut utiliser aggregate.
db.lesavions.aggregate([ {$unwind:"$vols"}, {$match:{"vols.site_arrivee":"NICE"}} ])
db.lesavions.find( {capacite:{$gt:200}}, {_id:1,modele:1,capacite:1} )
db.lesavions.find({ constructeur:"AIRBUS", site:"TOULOUSE" })
db.lesavions.aggregate([ {$match:{constructeur:"AIRBUS"}}, {$unwind:"$vols"}, {$match:{"vols.site_arrivee":"PARIS"}} ])
db.lesavions.aggregate([ {$unwind:"$vols"}, {$match:{ $or:[ {"vols.site_depart":"PARIS","vols.site_arrivee":"NICE"}, {"vols.site_depart":"TOULOUSE","vols.site_arrivee":"PARIS"}]}} ])
db.lesavions.find({ constructeur:{$in:["AIRBUS","BOEING"]} })
db.lesavions.find({ $or:[ {constructeur:"AIRBUS"}, {capacite:{$gt:200}}] })
db.lesavions.find({ constructeur:"AIRBUS", site:{$ne:"TOULOUSE"} })
db.lesavions.find({ constructeur:"AIRBUS", vols:{ $not:{ $elemMatch:{site_arrivee:"PARIS"} } } })
db.lesavions.aggregate([ {$match:{constructeur:{$ne:"AIRBUS"}}}, {$unwind:"$vols"}, {$match:{"vols.site_arrivee":"PARIS"}} ])
Les avions n’ont pas vraiment de nom c’est plutôt le modèle.
db.lesavions.aggregate([ {$unwind:"$vols"}, {$project:{ vol:"$vols.vol_id", avion:"$modele" }} ])
ça veut dire qu’on a au moins un vol pour l’avion ! Donc on peut utiliser le vols.0 pour récupérer la première valeur de notre tableau vols avec le mot clef $exists.
vols.0
$exists
db.lesavions.find({ "vols.0":{$exists:true}, {_id:1, constructeur:1,capacite:1} })
db.lesavions.aggregate([ {$ne:{constructeur:"BOEING"}}, {$unwind:"$vols"}, {$match:{"vols.site_arrivee":"PARIS"}} ])
Un peu plus compliqué à écrire. on recherche par Constructeur, on regroupe par Capacité et on vérifie qu’il y a bien la même capacité pour le même modèle que nous passons sous la forme de variable $modele. le $nb nous permet de savoir que nous avons bien trouvé un Boeing.
$modele
$nb
db.lesavions.aggregate([ {$match:{constructeur:"BOEING"}}, {$group:{ _id:"$capacite", avions:{$push:"$modele"}, nb:{$sum:1} }}, {$match:{nb:{$gt:1}}} ])
En fait, il faut comprendre marque comme constructeur.
db.lesavions.aggregate([ {$group:{ _id:"$constructeur", nombre:{$sum:1} }} ])
Ici, la question est, comment savoir qu’un avion est en service ? Normalement, il vole. On peut identifier les pilotes par leur identifiant. Ici, on peut utiliser $addToSet permettant d’ajouter les pilotes trouvés à notre liste de pilotes.
$addToSet
db.lesavions.aggregate([ {$unwind:"$vols"}, {$group:{ _id:"$_id", pilotes:{$addToSet:"$vols.pilote.id"} }}, {$project:{ nb_pilotes:{$size:"$pilotes"} }} ])
db.lesavions.aggregate([ {$unwind:"$vols"}, {$group:{ _id:"$vols.pilote.nom", nb_vols:{$sum:1} }} ])
db.lesavions.aggregate([ {$unwind:"$vols"}, {$group:{ _id:"$vols.pilote.id", nom:{$first:"$vols.pilote.nom"}, nb_vols:{$sum:1} }}, {$match:{nb_vols:{$gt:1}}} ])
db.lesavions.aggregate([ {$unwind:"$vols"}, {$match:{ "vols.site_depart":{$in:["NICE","PARIS"]} }} ])
db.lesavions.aggregate([ {$unwind:"$vols"}, {$match:{ $or:[ {"vols.site_depart":"NICE"}, {"vols.site_arrivee":"NICE"} ] }} ])
db.lesavions.aggregate([ {$unwind:"$vols"}, {$match:{ $expr:{$eq:["$vols.site_depart","$site"]} }} ])
db.lesavions.aggregate([ {$group:{ _id:null, moyenne:{$avg:"$capacite"} }} ])
db.lesavions.aggregate([ {$match:{constructeur:"BOEING"}}, {$group:{ _id:null, min:{$min:"$capacite"}, max:{$max:"$capacite"} }} ])
db.lesavions.aggregate([ {$match:{site:"PARIS"}}, {$group:{ _id:null, moyenne:{$avg:"$capacite"} }} ])
Par marque = par constructeur.
db.lesavions.aggregate([ {$group:{ _id:"$constructeur", moyenne:{$avg:"$capacite"} }} ])
db.lesavions.aggregate([ {$group:{ _id:null, total:{$sum:"$capacite"} }} ])
new Date().toLocaleTimeString()
db.lesavions.insertMany([ { _id: 100, constructeur: "AIRBUS", modele: "A320", capacite: 300, site: "NICE", vols: [ { vol_id: "IT100", site_depart: "NICE", site_arrivee: "PARIS", heure_depart: "07:00", heure_arrivee: "09:00", pilote: { id: 1, prenom: "Julien", nom: "DORE", site: "NICE" } }, { vol_id: "IT101", site_depart: "PARIS", site_arrivee: "TOULOUSE", heure_depart: "11:00", heure_arrivee: "12:00", pilote: { id: 2, prenom: "Camélia", nom: "JORDANA", site: "PARIS" } } ] }, { _id: 101, constructeur: "BOEING", modele: "B707", capacite: 250, site: "PARIS", vols: [ { vol_id: "IT102", site_depart: "PARIS", site_arrivee: "NICE", heure_depart: "12:00", heure_arrivee: "14:00", pilote: { id: 1, prenom: "Julien", nom: "DORE", site: "NICE" } }, { vol_id: "IT111", site_depart: "NICE", site_arrivee: "NANTES", heure_depart: "17:00", heure_arrivee: "19:00", pilote: { id: 4, nom: "ANN", site: "NANTES" } } ] }, { _id: 102, constructeur: "AIRBUS", modele: "A320", capacite: 300, site: "TOULOUSE", vols: [ { vol_id: "IT110", site_depart: "TOULOUSE", site_arrivee: "PARIS", heure_depart: "15:00", heure_arrivee: "16:00", pilote: { id: 2, prenom: "Camélia", nom: "JORDANA", site: "PARIS" } } ] }, { _id: 103, constructeur: "CARAVELLE", modele: "Caravelle", capacite: 200, site: "TOULOUSE", vols: [] }, { _id: 104, constructeur: "BOEING", modele: "B747", capacite: 400, site: "PARIS", vols: [] }, { _id: 105, constructeur: "AIRBUS", modele: "A320", capacite: 300, site: "GRENOBLE", vols: [ { vol_id: "IT103", site_depart: "GRENOBLE", site_arrivee: "TOULOUSE", heure_depart: "09:00", heure_arrivee: "11:00", pilote: { id: 3, prenom: "Philippe", nom: "KATERINE", site: "GRENOBLE" } }, { vol_id: "IT104", site_depart: "TOULOUSE", site_arrivee: "GRENOBLE", heure_depart: "17:00", heure_arrivee: "19:00", pilote: { id: 3, prenom: "Philippe", nom: "KATERINE", site: "GRENOBLE" } } ] }, { _id: 106, constructeur: "ATR", modele: "ATR42", capacite: 50, site: "PARIS", vols: [ { vol_id: "IT107", site_depart: "PARIS", site_arrivee: "BRIVE", heure_depart: "07:00", heure_arrivee: "08:00", pilote: { id: 9, nom: "PUNK", site: "PARIS" } }, { vol_id: "IT108", site_depart: "BRIVE", site_arrivee: "PARIS", heure_depart: "19:00", heure_arrivee: "20:00", pilote: { id: 9, nom: "PUNK", site: "PARIS" } } ] }, { _id: 107, constructeur: "BOEING", modele: "B727", capacite: 300, site: "LYON", vols: [ { vol_id: "IT105", site_depart: "LYON", site_arrivee: "PARIS", heure_depart: "06:00", heure_arrivee: "07:00", pilote: { id: 7, nom: "FARMER", site: "LYON" } }, { vol_id: "IT109", site_depart: "PARIS", site_arrivee: "LYON", heure_depart: "18:00", heure_arrivee: "19:00", pilote: { id: 7, nom: "FARMER", site: "LYON" } } ] }, { _id: 108, constructeur: "BOEING", modele: "B727", capacite: 300, site: "NANTES", vols: [] }, { _id: 109, constructeur: "AIRBUS", modele: "A340", capacite: 350, site: "BASTIA", vols: [ { vol_id: "IT106", site_depart: "BASTIA", site_arrivee: "PARIS", heure_depart: "10:00", heure_arrivee: "13:00", pilote: { id: 8, nom: "NAKAMURA", site: "BASTIA" } } ] } ])