cours-2023-2024 | Documents de mes cours pour l'année 2023-2024 | FX Jollois
Base de données NoSQL de type Document Store (orienté document)
Objectifs :
Plus d’informations sur leur site
Principe de base : les données sont des documents
BSON
)collections
JSON
JavaScript Object Notation
, créé en 2005{ "nom": "jollois", "prenom": "fx" }
[ 1, 5, 10]
string
et number
) et trois constantes (true
, false
, null
)Validation possible du JSON sur jsonlint.com/
JSON
{
"address": {
"building": "469",
"coord": [
-73.9617,
40.6629
],
"street": "Flatbush Avenue",
"zipcode": "11225"
},
"borough": "Brooklyn",
"cuisine": "Hamburgers",
"grades": [
{
"date": "2014-12-30 01:00:00",
"grade": "A",
"score": 8
},
{
"date": "2014-07-01 02:00:00",
"grade": "B",
"score": 23
}
],
"name": "Wendy'S",
"restaurant_id": "30112340"
}
BSON
: extension de JSON
Schéma dynamique
ALTER TABLE
ou de redesign de la basefind()
: pour tout ce qui est restriction et projectionaggregate()
: pour tout ce qui est calcul de variable, d’aggrégats et de manipulations diversesUtilisation du package pymongo
pymongo.MongoClient()
import pymongo
URI = 'mongodb+srv://user:user@cluster0.ougec.mongodb.net/test'
client = pymongo.MongoClient(URI) # enlever le paramètre URI si connexion locale
db = client.test
restaurants
Dans ce document, nous allons travailler sur une base des restaurants New-Yorkais.
Voici le premier document est présenté ci-dessous sur les plus de 25000 restaurants new-yorkais (base de test fournie par Mongo)
{
"_id" : ObjectId("58ac16d1a251358ee4ee87de"),
"address" : {
"building" : "469",
"coord" : [
-73.961704,
40.662942
],
"street" : "Flatbush Avenue",
"zipcode" : "11225"
},
"borough" : "Brooklyn",
"cuisine" : "Hamburgers",
"grades" : [
{
"date" : ISODate("2014-12-30T00:00:00Z"),
"grade" : "A",
"score" : 8
},
{
"date" : ISODate("2014-07-01T00:00:00Z"),
"grade" : "B",
"score" : 23
},
{
"date" : ISODate("2013-04-30T00:00:00Z"),
"grade" : "A",
"score" : 12
},
{
"date" : ISODate("2012-05-08T00:00:00Z"),
"grade" : "A",
"score" : 12
}
],
"name" : "Wendy'S",
"restaurant_id" : "30112340"
}
python
Les données JSON
sont similaires à un dictionnaire python
. Pour récupérer le premier document, nous utilisons la fonction find()
de l’objet créé m
.
d = db.restaurants.find(limit = 1)
d
L’objet retourné est un curseur, et non le résultat. Nous avons celui-ci lorsque nous utilisons d
dans une commande telle qu’une transformation en list
par exemple.
list(d)
Une fois le résultat retourné (un seul élément ici), le curseur ne renvoie plus rien.
list(d)
count_documents({})
pour dénombrer les documents
{}
est à mettre obligatoirementestimated_document_count()
pour estimer le nombre de documents, à utiliser de préférence en cas de multiples serveurs et de données massivesdb.restaurants.count_documents({})
db.restaurants.estimated_document_count()
Pour sélectionner les documents, nous allons utiliser le paramètre dans la fonction count_documents()
(ainsi que dans les fonctions distinct()
et find()
que nous verrons plus tard).
{}
: tous les documents{ "champs": valeur }
: documents ayant cette valeur pour ce champs{ condition1, condition2 }
: documents remplissant la condition 1 ET la condition 2"champs.sous_champs"
: permet d’accéder donc à un sous-champs d’un champs (que celui-ci soit un littéral ou un tableau){ "champs": { "$opérateur": expression }}
: utilisation d’opérateurs dans la recherche
$in
: comparaison à un ensemble de valeurs$gt
, $gte
, $lt
, $lte
, $ne
: comparaison (resp. greater than, greater than or equal, less than, less than or equal, not equal)db.restaurants.count_documents({ "borough": "Brooklyn" })
db.restaurants.count_documents({ "borough": "Brooklyn", "cuisine": "French" })
db.restaurants.count_documents({ "borough": "Brooklyn", "cuisine": { "$in": ["French", "Italian"]} })
db.restaurants.count_documents(
{
"borough": "Brooklyn",
"cuisine": { "$in": ["French", "Italian"]}
}
)
street
du champs address
db.restaurants.count_documents(
{
"address.street": "Franklin Street"
}
)
db.restaurants.count_documents(
{
"grades.score": 0
}
)
db.restaurants.count_documents(
{
"grades.score": { "$lte": 5 }
}
)
On peut aussi voir la liste des valeurs distinctes d’un attribut, avec la fonction distinct()
.
borough
), pour tous les restaurantsdb.restaurants.distinct(key = "borough")
db.restaurants.distinct(
key = "cuisine",
query = { "borough": "Brooklyn" }
)
db.restaurants.distinct(
key = "grades.grade",
query = { "borough": "Brooklyn" }
)
find()
pour réaliser les restrictions et projectionslimit
pour n’avoir que les $n$ premiers documentssort
pour effectuer un tri des documentsDataFrame
(du module pandas
)
Dans la fonction find()
, pour choisir les champs à afficher, le deuxième paramètre permet de faire une projection avec les critères suivants :
_id
){ "champs": 1 }
: champs à afficher{ "champs": 0 }
: champs à ne pas afficher_id
)
{ "_id": 0, "champs": 1, ...}
Toujours dans la fonction find()
, il est possible de faire le tri des documents, avec le paramètre sort
qui prend un tuple composé de 1 ou plusieurs tuples indiquant les critères de tri
( "champs", 1 )
: tri croissant( "champs", -1 )
: tri décroissantDans ces fonctions, on peut aussi limiter l’exploration à une partie, avec les paramètres suivant :
limit
: restreint le nombre de résultats fournisskip
: ne considère pas les n premiers documentsNotez le contenu des colonnes address
et grades
.
import pandas
pandas.DataFrame(list(db.restaurants.find(limit = 5)))
"street"
et "borough"
)c = db.restaurants.find({ "name": "Shake Shack" }, { "address.street": 1, "borough": 1 })
pandas.DataFrame(list(c))
c = db.restaurants.find(
{ "name": "Shake Shack" },
{ "_id": 0, "address.street": 1, "borough": 1 }
)
pandas.DataFrame(list(c))
c = db.restaurants.find(
{"borough": "Queens", "grades.score": { "$gte": 50}},
{"_id": 0, "name": 1, "grades.score": 1, "address.street": 1},
limit = 5
)
pandas.DataFrame(list(c))
c = db.restaurants.find(
{"name": "Shake Shack", "borough": {"$in": ["Queens", "Brooklyn"]}},
{"_id": 0, "address.street": 1, "borough": 1}
)
pandas.DataFrame(list(c))
c = db.restaurants.find(
{"borough": "Queens", "grades.score": { "$gt": 50}},
{"_id": 0, "name": 1, "address.street": 1},
sort = (("address.street", -1), ("name", 1))
)
pandas.DataFrame(list(c))
Nécessitent une recherche sur la toile pour compléter ce qu’on a déjà vu dans ce TP.