Manipulation de mongoDB avec Python-Partie 6: agrégat-

Portée de cet article

Dans cet article, je décrirai comment utiliser l'agrégat (fonction d'agrégation en SQL) après la connexion à mongodb avec Python. Veuillez consulter les articles suivants pour savoir comment démarrer mongodb et installer pymongo. https://qiita.com/bc_yuuuuuki/items/2b92598434f6cc320112

Données de préparation

Pour les données de préparation, nous utiliserons les informations d'article de Qiita qui ont plongé dans mongoDB dans l'article suivant [Python] J'ai mis les informations de l'article de Qiita dans mongoDB

Comment utiliser l'agrégat

Comment utiliser l'agrégat de mongoDB ne me vient pas si vous êtes habitué à SQL. Le tableau ci-dessous est un tableau de comparaison de SQL et d'agrégat.

SQL aggregate
WHERE $match
GROUP BY $group
HAVING $match
SELECT $project
ORDER BY $sort
LIMIT $limit
SUM() $sum
COUNT() $sum

classe d'opération de mongoDB

Je crée diverses classes qui utilisent mongoDB en utilisant pymongo.

mongo_sample.py


from pymongo import MongoClient

class MongoSample(object):

    def __init__(self, dbName, collectionName):
        self.client = MongoClient()
        self.db = self.client[dbName] #Définir le nom de la base de données
        self.collection = self.db.get_collection(collectionName)

    def aggregate(self, filter, **keyword):
        return self.collection.aggregate(filter, keyword)

Je crée juste une fonction pour appeler l'agrégat.

Obtenir des données de mongoDB

Le premier est le code.

aggregate_sample.py


from mongo_sample import MongoSample
import pprint
# arg1:DB Name
# arg2:Collection Name
mongo = MongoSample("db", "qiita")

#Valeur maximum
pipeline = [
    {"$group":{ "_id":"title","page_max_view":{"$max":"$page_views_count"}}}
]
results = mongo.aggregate(pipeline)
print("------------------------Valeur maximum-----------------------------")
pprint.pprint(list(results))

#valeur minimum
pipeline = [
    {"$group":{ "_id":"title","page_min_view":{"$min":"$page_views_count"}}}
]
results = mongo.aggregate(pipeline)
print("------------------------valeur minimum-----------------------------")
pprint.pprint(list(results))

#Valeur moyenne
pipeline = [
    {"$group":{ "_id":"average","page_average_view":{"$avg":"$page_views_count"}}}
]

#total
pipeline = [
    {"$group":{"_id":"page_total_count","total":{"$sum":"$page_views_count"}}}
]
results = mongo.aggregate(pipeline)
print("------------------------Valeur moyenne-----------------------------")
pprint.pprint(list(results))

#Comptez le nombre d'occurrences pour chaque balise
pipeline = [
    { "$unwind": "$tag_list"}, 
    { "$group": { "_id": "$tag_list", "count": { "$sum":1}}},
    { "$sort": {"count": -1, "_id":1}}
]

results = mongo.aggregate(pipeline)
print("------------------------Valeur globale-----------------------------")
pprint.pprint(list(results))

Ce que vous faites n’est pas grave. La valeur maximale, la valeur minimale, la valeur moyenne et le nombre pour chaque balise sont acquises.

pprint doit être installé.

pip install pprint

Nous comparerons chacun avec la méthode de fonctionnement de mongoDB.

Maximum / minimum / moyenne / total

Tout d'abord, la commande mongoDB L'exemple n'est que la valeur maximale. Si max est changé en min, avg ou sum, il devient la valeur minimale / moyenne / maximale.

db.qiita.aggregate([{$group:{_id:"page_max_views",total:{$max:"$page_views_count"}}}])
pipeline = [
    {"$group":{ "_id":"title","page_max_view":{"$max":"$page_views_count"}}}
]

Résultat d'exécution

[{'_id': 'title', 'page_max_view': 2461}]

Cette méthode a fixé le "_id" à "title" et a permis d'obtenir la valeur maximale dans tous les enregistrements.

Cependant, je souhaite afficher le titre de l'article car je veux savoir quel article est le plus lu.

commande mongoDB

> db.qiita.aggregate([{$project:{title:1,page_views_count:1}},{$group:{_id:"$title", total:{$max:"$page_views_count"}}},{$sort:{total:-1}}])
 {"_id": "Fonctionnement de mongodb avec Python - Partie 2: find-", "total": 2461}
 {"_id": "Fonctionnement de mongodb avec Python-Part 3: update-", "total": 1137}
 {"_id": "Fonctionnement de mongodb avec Python - Partie 4: insert-", "total": 1102}
 {"_id": "Diverses conditions de recherche utilisant pymongo (AND / OR / correspondance partielle / recherche par plage)", "total": 1019}
 (Omis)

Avec cette commande, je pouvais voir le titre de l'article et le nombre de fois où la page était consultée. De toute évidence, cela n'a pas beaucoup de sens car il est regroupé par nom d'article. .. Si c'est la valeur maximale qui ne nécessite pas de regroupement, il semble bon de trier avec trouver et définir une limite.

Essayez d'obtenir la valeur maximale de chaque tag1.

> db.qiita.aggregate([{$group:{_id:"$tag1", total:{$max:"$page_views_count"}}},{$sort:{total:-1}}])
{ "_id" : "Python", "total" : 2461 }
{ "_id" : "Vagrant", "total" : 946 }
{ "_id" : "Java", "total" : 617 }
{ "_id" : "Hyperledger", "total" : 598 }
{ "_id" : "solidity", "total" : 363 }
{ "_id" : "Ethereum", "total" : 347 }
 {"_id": "blockchain", "total": 232}
{ "_id" : "Blockchain", "total" : 201 }
{ "_id" : "coverage", "total" : 199 }

Oui. Je l'ai eu avec un bon sentiment.

Pour le moment, je vais également modifier le code python.

# Valeur maximum
pipeline = [
    {"$group":{ "_id":"$tag1","page_max_view":{"$max":"$page_views_count"}}}
]
results = mongo.aggregate(pipeline)
 print ("------------------------ Valeur maximale --------------------- -------- ")
pprint.pprint(list(results))

Agrégation par tag

Je voudrais compter le nombre d'articles écrits pour chaque balise. L'agrégation utilise un élément appelé tag_list, qui ressemble à ceci:

> db.qiita.find({},{_id:0,tag_list:1})
{ "tag_list" : [ "Python", "MongoDB", "Python3", "pymongo" ] }
{ "tag_list" : [ "Python", "Python3" ] }
 {"tag_list": ["Python", "Python3", "Blockchain", "Blockchain", "Hyperledger-Iroha"]}
 {"tag_list": ["Blockchain", "Blockchain", "Hyperledger-Iroha"]}
{ "tag_list" : [ "Blockchain", "Ethereum", "Hyperledger", "Hyperledger-sawtooth" ] }
 {"tag_list": ["Blockchain", "Hyperledger", "Hyperledger-sawtooth"]}
 {"tag_list": ["Java", "Blockchain", "Hyperledger", "Hyperledger-Iroha"]}
 {"tag_list": ["Blockchain", "Hyperledger", "Hyperledger-Iroha"]}
 {"tag_list": ["Java", "Ethereum", "Blockchain", "Hyperledger", "Hyperledger-Iroha"]}
 {"tag_list": ["Java", "Blockchain", "Hyperledger", "Hyperledger-Iroha"]}
{ "tag_list" : [ "Hyperledger", "Hyperledger-Iroha", "Hyperledger-burrow", "Hyperledger-sawtooth", "Hyperledger-besu" ] }
{ "tag_list" : [ "Vagrant", "VirtualBox", "Hyper-V" ] }
 {"tag_list": ["Java", "Ethereum", "solidity", "blockchain", "web3j"]}
 {"tag_list": ["Java", "Ethereum", "blockchain", "web3j"]}
 {"tag_list": ["Java", "Ethereum", "blockchain", "web3j"]}
 {"tag_list": ["Java", "Ethereum", "blockchain", "web3j"]}
 {"tag_list": ["Java", "Ethereum", "solidity", "blockchain", "web3j"]}
 {"tag_list": ["Java", "Ethereum", "blockchain", "web3j"]}
 {"tag_list": ["Java", "Ethereum", "blockchain", "web3j"]}
 {"tag_list": ["Ethereum", "blockchain"]}

Il serait assez ennuyeux d'agréger les données stockées dans ce format en SQL. ..

Dans mongoDB, en utilisant quelque chose appelé dérouler, il est possible de diviser et d'agréger les données au format LIST.

> db.qiita.aggregate( { $project:{tag_list:1}}, { $unwind: "$tag_list"}, { $group: { _id: "$tag_list", count: { $sum:1}}},{ $sort: {"count": -1, "_id":1}} )
 {"_id": "blockchain", "count": 16}
{ "_id" : "Ethereum", "count" : 11 }
{ "_id" : "Java", "count" : 10 }
{ "_id" : "Python", "count" : 9 }
{ "_id" : "Python3", "count" : 9 }
{ "_id" : "Hyperledger", "count" : 7 }
{ "_id" : "Hyperledger-Iroha", "count" : 7 }
{ "_id" : "MongoDB", "count" : 7 }
{ "_id" : "web3j", "count" : 7 }
{ "_id" : "solidity", "count" : 4 }
{ "_id" : "Blockchain", "count" : 3 }
{ "_id" : "Hyperledger-sawtooth", "count" : 3 }
{ "_id" : "Hyper-V", "count" : 1 }
{ "_id" : "Hyperledger-besu", "count" : 1 }
{ "_id" : "Hyperledger-burrow", "count" : 1 }
{ "_id" : "Vagrant", "count" : 1 }
{ "_id" : "VirtualBox", "count" : 1 }
{ "_id" : "coverage", "count" : 1 }
{ "_id" : "pymongo", "count" : 1 }
{ "_id" : "truffle", "count" : 1 }

Le code python n'inclut pas "{" $ project ": {" tag_list ": 1}}". Le résultat n'a pas changé avec ou sans lui. Je ne sais pas comment utiliser ce projet.

Impressions

De nombreuses parties sont difficiles à comprendre si vous êtes habitué à SQL, mais il semble qu'une agrégation flexible puisse être effectuée en utilisant le déroulement, etc.

Article associé

Recommended Posts

Manipulation de mongoDB avec Python-Partie 6: agrégat-
accès mongodb avec pymongo
[Note] Faites fonctionner MongoDB avec Python
Principes de base pour toucher MongoDB avec MongoEngine
Manipuler des chaînes avec un groupe pandas par
Lire les variables d'environnement système avec python-partie 1
Lire les variables d'environnement système avec python-partie 2