Manipuler les données avec MongoDB – Vers la science des données
Il existe de nombreuses façons de lire vos données. Vous pouvez filtrer, grouper, trier, limiter, compter, additionner ainsi que de nombreuses autres fonctions fournies par MongoDB. Je vais passer en revue quelques notions de base.
find_one ()
find_one()
nous permet de récupérer les premières données de notre base de données
client.sample_mflix.movies.find_one()
Finder, projection
finder
nous permet de spécifier les clés et la valeur que nous voulons filtrer. projection
nous permet de spécifier ce que nous voulons retourner.
finder = {
'countries': {'$all': ['USA', 'Italy']}
}
projection={
'title':1,
'countries':1,
'rated': 1
}
pprint.pprint(list(client.sample_mflix.movies.find(finder,projection)))
-
'$all'
signifie que le'countries'
le champ DOIT contenir TOUT ce qui a été spécifié. Dans notre cas, nous voulons récupérer des films réalisés aux États-Unis et en Italie. Notez que cette syntaxe est très similaire à celle que vous saisiriez dans la barre de recherche de Compass. - En dessous de
projection
, nous spécifions les clés que nous voulons retourner. Définissez la valeur sur 1 si vous voulez retourner et 0 si vous ne voulez pas retourner cette clé. Si vous omettez la clé, elle sera traitée comme vous ne voulez pas que cette clé soit retournée.
Agrégat
La plupart de la lecture et de l’écriture des données dans PyMongo peut se faire à l’aide d’un agrégation cadre. L’agrégation est une méthode de classe de collection. Cela signifie qu’il ne peut être appliqué qu’aux collections / tables. Un cadre d’agrégation nécessite un pipeline ou un «modèle»:
pipeline = [
{
'$group': {
'_id': {"rated": "$rated"},
'count': {"$sum": 1}
}
},
{
'$sort': {'count': -1}
}
]pprint.pprint(list(client.sample_mflix.movies.aggregate(pipeline)))
-
'$group
étape nous permet de regrouper notre sortie par les clés spécifiées. -
'_id':{"rated":"$rated"}
est l’endroit où nous spécifions la clé que nous voulons regrouper. Dans ce cas, je veux regrouper par l’uniquerated
. Le signe dollar ($) est un identifiant de chemin de champ. Il nous permet de récupérer les valeurs exactes de notre base de données. -
'count': {"$sum": 1}
augmentera automatiquement le nombre de 1 pour chaque uniquerated
. -
'$sort':{'count': -1}
indique à notre pipeline de trier les résultats par ordre décroissant (-1) de comptage.
Facette
Facet nous permet de bien regrouper nos données. C’est similaire à $group
mais cela nous permet de personnaliser la façon dont nous voulons regrouper nos données.
pipeline = [
{
'$sortByCount': '$countries'
},
{
'$facet':{
'top country combinations': [{'$limit': 10}],
'unusual combinations shared by' : [{
'$skip' : 10
},
{
'$bucketAuto': {
'groupBy': "$count",
'buckets': 5,
'output': {
'country combinations': {"$sum":1}
}
}
}
]
}
}
]pprint.pprint(list(client.sample_mflix.movies.aggregate(pipeline)))
-
‘top country combinations’: [{‘$limit’: 10}]
indique à notre pipeline de produire les 10 premiers pays et leurs comptes respectifs -
‘$skip’ : 10
nous permet de sauter les 10 premiers résultats car il est déjà classé sous'top country combinations'
-
‘$bucketAuto’: {
est une méthode qui regroupera les résultats restants dans le nombre maximal spécifié de compartiments / bacs par une métrique spécifique.
Dans les résultats, nous sommes d’abord accueillis par les 10 premiers pays en termes de nombre de films. Passons à autre chose, nous avons 3 seaux. Pour MongoDB, min
est inclusif et max
est exclusif. Cela signifie qu’il existe des films dont la combinaison de pays est similaire à un minimum de 2 autres films et à un maximum de 6 autres films. Le nombre de ces films est de 469. D’autre part, nous avons également min: 1
et max: 1
. Cela signifie qu’il existe 1695 films avec une combinaison unique de pays.
Nettoyer, filtrer et modifier les données dans une autre collection
Pour cette section, je ferai référence à l’original movies_initial.csv
car il est impur. Nous allons nettoyer une partie des données avant de les exporter dans une autre collection nommée movies_subset
.
pipeline = [
{
'$limit': 100
},
{
'$project': {
'title': 1,
'directors': {'$split': ["$director", ", "]},
'released': {
'$cond': {
'if': {'$ne': ["$released", ""]},
'then': {
'$dateFromString': {
'dateString': "$released"
}
},
'else': ""}},
'imdb': {
'id': "$imdbID",
'rating': "$imdbRating",
'votes': "$imdbVotes"
}
}
},
{
'$out': "movies_subset"
}
]pprint.pprint(list(client.mflix.movies_initial.aggregate(pipeline)))
- Nous limitons d’abord le nombre de données à récupérer à 100
- Nous voulons le champ titre
- Le champ de répertoire est divisé en un tableau. Par exemple,
"Mike, Tom, Harry"
sera divisé en["Mike", "Tom", "Harry"]
- Dans le champ publié, ce que nous faisons est de convertir essentiellement une chaîne de date et d’heure en un objet DateTime si le champ n’est pas vide. Si le champ est vide, nous retournerons simplement une chaîne vide.
-
‘if’: {‘$ne’: [“$released”, “”]}
spécifie que si notre champ libéré n’est pas égal à une chaîne vide, nous continuerons avec ce qui est dans la clause. - finalement
$out
nous permet d’exporter les données finales dans une nouvelle collection
Filtre
Il existe 3 façons de filtrer vos résultats.
- $ match
pipeline = [
{
'$match': {'countries': ['USA', 'Italy']}
}
]
pprint.pprint(list(client.sample_mflix.movies.aggregate(pipeline)))
2. finder
finder = {'countries': ['USA', 'Italy']}
pprint.pprint(list(client.sample_mflix.movies.find(finder)))
3. Compas
{'countries': ['USA', 'Italy'], 'rated' : "UNRATED"}
Tous les 3 ci-dessus sont les mêmes. Eh bien… pas vraiment pareil, j’ai glissé un filtre supplémentaire à l’intérieur du point 3. Mais vous pouvez voir comment vous pouvez entrer plusieurs filtres sur une seule ligne!
Notez que $all
et $match
c’est très differant. $match
nécessite une correspondance exacte. $all
renvoie le résultat tant que les valeurs spécifiées sont trouvées.
Les opérateurs
Il existe certains comparatifs les opérateurs que vous pouvez inclure dans vos filtres ou recherches.
# find all movies except the ones which are of adult genre
filters = {
'year': {'$gte': 1989, '$lt': 2000},
'genre': { '$not' : {'$eq': 'Adult'} }
}pprint.pprint(list(client.sample_mflix.movies.find(filters)))
-
$gte
signifie «supérieur ou égal à» -
$lt
signifie «moins de» -
{ ‘$not’ : {‘$eq’: ‘Adult’} }
signifie que nous voulons des valeurs qui ne sont pas égales à «Adulte»
Il y a plus de 20 opérateurs. Je vous recommande vivement de consulter le Documentation!
Trier et limiter
Le tri et la limitation sont très simples. Nous les combinons souvent pour rendre notre sortie lisible. Non seulement vous pouvez les saisir dans votre infrastructure d’agrégation, mais vous pouvez également les utiliser comme méthode Python.
from pymongo import DESCENDING
sort_key = "imdb.rating"movies = client.sample_mflix.movies.find({})
.sort(sort_key, DESCENDING).limit(100)list(movies)
Tout d’abord, nous spécifions la clé selon laquelle nous voulons trier nos valeurs. Notez que nous avons saisi imdb.rating
comme rating
(un scalaire) est imbriqué à l’intérieur imdb
(un tableau).
Notez que dans notre .find()
, nous entrons un dictionnaire vide. Cela indique à notre chercheur de rechercher toute la collection.
Enfin, nous trions nos résultats par ordre décroissant et ne renvoyons que les 100 premiers résultats.