Vous êtes sur la page 1sur 58

Bases de données

NOSQL
LP SIBD
Pr. Youssef LEFDAOUI

Année Universitaire 2020 -2021

Pr Y.Lefdaoui NOSQL Slide 1


Module NoSQL : Les objectifs
Partie I

u  Contexte d'utilisation de bases de données NOSQL.


u  Les modèles de bases de données NoSQL
u  Les systèmes de gestion de bases de données NoSQL
orientées documents
u  Les caractéristiques du système MongoDB.
u  Installer et configurer le SGBD MongoDB
u  Manipuler les objets et les données dans MongoDB
u  Implémenter une application sous MongoDB
u  Améliorer les performances

Pr Y.Lefdaoui NOSQL Slide 2


Nouveaux besoins en gestion de données

Pr Y.Lefdaoui NOSQL Slide 3


Nouveaux besoins en gestion de données

Pr Y.Lefdaoui
NOSQL
Slide 4
Le V de la Valeur

Pr Y.Lefdaoui NOSQL Slide 5


Les évolutions...
●  Nouvelles Données : ➔ très gros volumes,
•  Web 2.0 : Facebook, Twitter, news, données pas ou faiblement structurées
blogs, ...
•  LOD : graphes, ontologies, ...
•  Flux : capteurs, GPS, …
●  Nouveaux Traitements : ➔ transformation,
•  Moteurs de recherche agrégation,
•  Extraction, analyse, ... indexation
•  Recommandation, filtrage collaboratif,

●  Nouvelles Infrastructures :
•  Cluster, réseaux mobiles,
➔ distribution,
microprocesseurs multi-coeurs, … parallélisation,
redondance

Pr Y.Lefdaoui NOSQL Slide 6


Quelle technologie choisir pour ses données ?
●  Il existe un très grand nombres de solutions techniques différentes !

Pr Y.Lefdaoui NOSQL Slide 7


Differents usages des donnees

Pr Y.Lefdaoui NOSQL Slide 8


Limites de bases de données relationnelles

Pr Y.Lefdaoui NOSQL Slide 9


Limites des systèmes SGBD classiques

Pr Y.Lefdaoui NOSQL Slide 10


Limites des systèmes SGBD classiques

Pr Y.Lefdaoui NOSQL Slide 11


Caractéristiques générales de BD. NOSQL

Pr Y.Lefdaoui NOSQL Slide 12


Taxonomie des bases NoSQL

Pr Y.Lefdaoui NOSQL Slide 13


Key/Value Store

Pr Y.Lefdaoui NOSQL Slide 14


Classement des moteurs NoSQL Par schémas de données
Les moteurs orientés colonnes

•  Chaque colonne est définie par un


couple clé-valeur

•  Une super-colonne est un couple clé-


valeur dont la valeur est une colonne

•  Une famille de colonnes permet de


regrouper plusieurs colonnes ou super-
colonnes.
•  Implémentations existantes
»  HBase(Open Source de BigTablede Google)
»  Cassandra (fondation Apache)
»  SimpleDB(Amazon)

Pr Y.Lefdaoui NOSQL Slide 15


Les moteurs orientés colonnes

•  Chaque colonne est définie par un


couple clé-valeur

•  Une super-colonne est un couple clé-


valeur dont la valeur est une colonne

•  Une famille de colonnes permet de


regrouper plusieurs colonnes ou super-
colonnes.
•  Implémentations existantes
»  HBase(Open Source de BigTablede Google)
»  Cassandra (fondation Apache)
»  SimpleDB(Amazon)

Pr Y.Lefdaoui NOSQL Slide 16


BD orientée document

Pr Y.Lefdaoui NOSQL Slide 17


BD NoSQL orientée document

Pr Y.Lefdaoui NOSQL Slide 18


BD NoSQL orientée document

Pr Y.Lefdaoui NOSQL Slide 19


BD NoSQL orientée document

Pr Y.Lefdaoui NOSQL Slide 20


MongoDB
Document

●  Le champ _id
•  Seul champ obligatoire, utilisé comme clef primaire dans une collection
●  Les noms des champs ne peuvent pas commencer par un $ ou contenir le
caractère « . »

Pr Y.Lefdaoui NOSQL Slide 21


MongoDB
Structures de Documents
●  Deux manières des relations entre les données: Références et Données Imbriquées
●  Références
•  Inclusion de liens ou références d’un document à un autre
•  C’est à l’application de résoudre ces références pour accéder aux données associées
•  On dit qu’on utilise des Modèles de Données Normalisés

Pr Y.Lefdaoui NOSQL Slide 22


MongoDB
Structures de Documents
●  Données Imbriquées (Embedded Data)
•  Sauvegarde des données associées dans la même structure de documents
•  Il est possible d’inclure des documents dans un champ ou un tableau
•  Permet aux applications d’extraire et manipuler plusieurs niveaux de hiérarchie en une seule
instruction
•  Ce sont les Modèles de Données Dénormalisés

Pr Y.Lefdaoui NOSQL Slide 23


MongoDB
Lecture
●  MongoDB fournit une méthode db.collection.find() pour l’extraction de
données
•  § Accepte les critères de la requête, ainsi que les projections
•  § Retourne un curseur vers les documents correspondants

●  Fournit également une méthode db.collection.findOne() retournant un seul


document

Pr Y.Lefdaoui NOSQL Slide 24


MongoDB
Terminologie

Pr Y.Lefdaoui NOSQL Slide 25


BD NoSQL orientées graphes

Pr Y.Lefdaoui NOSQL Slide 26


BD NoSQL orientées graphes

Pr Y.Lefdaoui NOSQL Slide 27


MongoDB : les fondements

Pr Y.Lefdaoui NOSQL Slide 28


Structure de données

Pr Y.Lefdaoui NOSQL Slide 29


Les documents

Pr Y.Lefdaoui NOSQL Slide 30


Instance mongodb

Pr Y.Lefdaoui NOSQL Slide 31


Bases de données (1)

Pr Y.Lefdaoui NOSQL Slide 32


Bases de données (2)
Effacement d’une base
> show dbs
admin 0.000GB
db‐films 0.000GB
local 0.000GB

> db
db‐films

> db.dropDatabase()
{ "dropped" : "db‐films", "ok" : 1 }
> show dbs
admin 0.000GB
local 0.000GB

> db
db‐films
Pr Y.Lefdaoui NOSQL Slide 33
Bases de données (3)
Le client MongoDB permet de définir et d’exécuter du code Java Script

> function fact(n) { Le client MongoDB contient un


... if (n == 1) return 1 interpréteur de Java Script permettant
... else return (n* fact(n‐1)) de définir des fonctions et des variables
... }
> fact (2)
2

La définition de fonctions de calcul en Java Script sera très utile/nécessaire pour


l’écriture des fonctions map() et reduce() des Map‐Reduce (voir plus loin)

Pr Y.Lefdaoui NOSQL Slide 34


Définition d'un schéma de données avec MongoDB
Les collections

Pr Y.Lefdaoui NOSQL Slide 35


Définition d'un schéma de données avec MongoDB
Les collections

Pr Y.Lefdaoui NOSQL Slide 36


Insertion de documents

Pr Y.Lefdaoui NOSQL Slide 37


[
{
"_id": "movie:1",
"title": "Vertigo",
"year": "1958",
"director": {
"_id": "artist:3",
"last_name": "Hitchcock",
"first_name": "Alfred",
"birth_date": "1899"
},
"actors": [
{
"_id": "artist:15",
"first_name": "James",
"last_name": "Stewart",
},
{
"_id": "artist:16",
"first_name": "Kim",
"last_name": "Novak",
}
]
},
{
"_id": "movie:2",
"title": "Alien",
...
}
]
Pr Y.Lefdaoui NOSQL Slide 38
Importation de données

• Le démon mongod doit être lancé, et mongoimport s’y connectera


• L’option ‐‐mode permet de préciser si on ajoute/mélange/remplace les données
déjà présente dans la collection
• L’option ‐‐jsonArray permet d’importer des tableaux de documents JSON
• La commande mongoimport est riche en options de fonctionnement (voir la doc
technique de MongoDB)
Gestion de l’ajout des nouvelles données :
• Si la donnée lue ne possède pas de ‘’_id’’ : alors un ‘’_id’’ sera créé et lui sera affecté.
• Si la donnée lue possède un ‘’_id’’ déjà utilisé dans une donnée de la base :
• ‐‐mode insert : indique une erreur
• ‐‐mode upsert : remplace l’ancienne donnée par la donnée lue
• ‐‐mode merge : ajoute les nouveaux champs présents dans le fichier JSON, remplace ceux déjà existants et
redéfinis dans la donnée lue.
En supposant que ce tableau est sauvegardé dans movies.json, on peut l’importer dans la collection movies de la
base nfe204 avec la commande suivante:
mongoimport -d nfe204 -c movies --file movies.json --jsonArray

mongoimport -d nfe204 -c movies --file movies.json --jsonArray


Pr Y.Lefdaoui NOSQL Slide 39
Recherche

Pr Y.Lefdaoui NOSQL Slide 40


Recherche
fonction find() (1)

Pr Y.Lefdaoui NOSQL Slide 41


Recherche
fonction find() (1)

Pr Y.Lefdaoui NOSQL Slide 42


Recherche
fonction find() (2)

Pr Y.Lefdaoui NOSQL Slide 43


Recherche
fonction find() (3)

Pr Y.Lefdaoui NOSQL Slide 44


Recherche
fonction findOne()

Pr Y.Lefdaoui NOSQL Slide 45


Insertion des données dans MongoDB

Pr Y.Lefdaoui NOSQL Slide 46


Insertion des données dans MongoDB

Pr Y.Lefdaoui NOSQL Slide 47


Consultation des données Mongodb

Pr Y.Lefdaoui NOSQL Slide 48


db.collection.find(query, projection)

§  Sélectionne des documents dans une collection ou une vue et renvoie un curseur
sur les documents sélectionnés.

Projection : détermine quels champs sont retournés dans les documents


correspondants.
{ field1: true | false , field2: : true | false ... }

{ "_id": "apples", "qty": 5 }


{ "_id": "bananas", "qty": 7 }
{ "_id": "oranges", "qty": { "in stock": 8, "ordered": 12 } }
{ "_id": "avocados", "qty": "fourteen" }

db.collection.find( { qty: { $gt: 4 } } )

{ "_id": "apples", "qty": 5 }


{ "_id": "bananas", "qty": 7 }

Pr Y.Lefdaoui NOSQL Slide 49


Requêtes utilisant les opérateurs
db.bios.find({ _id: { $in: [ 5, ObjectId("507c35dd8fada716c89d0013") ] } })

db.bios.find( { birth: { $gt: new Date('1950-01-01') } } )

db.bios.find( { birth: { $gt: new Date('1940-01-01'), $lt: new Date('1960-01-01') } } )

db.bios.find( {
birth: { $gt: new Date('1920-01-01') },
death: { $exists: false }
})

db.bios.find(
{ name: { first: "Yukihiro", last: "Matsumoto" } }
)

db.bios.find(
{"name.first": "Yukihiro",
"name.last": "Matsumoto"
})
Pr Y.Lefdaoui NOSQL Slide 50
Requête sur des éléments d'un tableau
db.bios.find( { contribs: "UNIX" } )

db.bios.find( { contribs: { $in: [ "ALGOL", "Lisp" ]} } )

db.bios.find( { contribs: { $all: [ "ALGOL", "Lisp" ] } } )

db.bios.find( { contribs: { $size: 4 } } )

db.bios.find(
{ "awards.award": "Turing Award" }
)

db.bios.find(
{ awards: { $elemMatch: { award: "Turing Award", year: { $gt: 1980 } } } }
)

Pr Y.Lefdaoui NOSQL Slide 51


Interroger un tableau
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);

// un tableau avec exactement deux éléments, "red" et "blank",


db.inventory.find( { tags: ["red", "blank"] } )

// contient à la fois les éléments "red" et "blank", sans tenir compte de l'ordre ou des //
autres éléments du tableau.
db.inventory.find( { tags: { $all: ["red", "blank"] } } )

// contient au moins un élément dont la valeur est supérieure à 25.


db.inventory.find( { dim_cm: { $gt: 25 } } )

Pr Y.Lefdaoui NOSQL Slide 52


Interroger un tableau
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);

// un élément peut satisfaire la condition supérieure à 15 et un autre élément peut


// satisfaire la condition inférieure à 20, ou un seul élément peut satisfaire les deux:
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )

// contient au moins un élément qui est supérieur à ($ gt) 22 et inférieur à ($ lt) 30:
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )

// le deuxième élément du tableau dim_cm est supérieur à 25:


db.inventory.find( { "dim_cm.1": { $gt: 25 } } )

Pr Y.Lefdaoui NOSQL Slide 53


Interroger un tableau
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
{ item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
{ item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
{ item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
{ item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);

// un élément peut satisfaire la condition supérieure à 15 et un autre élément peut


// satisfaire la condition inférieure à 20, ou un seul élément peut satisfaire les deux:
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )

// contient au moins un élément qui est supérieur à ($ gt) 22 et inférieur à ($ lt) 30:
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )

// sélectionne les documents où les balises de tableau ont 3 éléments.


db.inventory.find( { "tags": { $size: 3 } } )

Pr Y.Lefdaoui NOSQL Slide 54


Interroger un tableau de documents incorporés
db.inventory.insertMany( [
{ item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
{ item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
{ item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
{ item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);

// Le tableau correspond au document spécifié:


db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )
db.inventory.find( { "instock": { qty: 5, warehouse: "A" } } ) // vide

// tableau a au moins un document incorporé contenant le champ qty dont la


/ /valeur est inférieure ou égale à 20:
db.inventory.find( { 'instock.qty': { $lte: 20 } } )

// Le tableau a pour premier élément un document contenant le champ qty dont la


// valeur est inférieure ou égale à 20.
db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )
Pr Y.Lefdaoui NOSQL Slide 55
Interroger un tableau de documents incorporés
db.inventory.insertMany( [
{ item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
{ item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
{ item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
{ item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);

// Ltableau a au moins un document incorporé qui contient à la fois le champsqty


//égale à 5 et le champs warehouse égale à A:
db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )

db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )

Pr Y.Lefdaoui NOSQL Slide 56


db.collection.aggregate()
{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }

// les documents dont l'état est égal à "A", regroupe les documents correspondants dans
// le champ cust_id, calcule le total de chaque champ cust_id à partir de la somme du
//champ du montant et trie les résultats en fonction du champ total par ordre
//décroissant:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } }
])

Pr Y.Lefdaoui NOSQL Slide 57


db.collection.aggregate()
{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }

// les documents dont l'état est égal à "A", regroupe les documents correspondants dans
// le champ cust_id, calcule le total de chaque champ cust_id à partir de la somme du
//champ du montant et trie les résultats en fonction du champ total par ordre
//décroissant:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } }
])

Pr Y.Lefdaoui NOSQL Slide 58

Vous aimerez peut-être aussi