From 845038a8fd62dd192169e6f3553571eb3d4ddc81 Mon Sep 17 00:00:00 2001 From: NGUYEN Anh Vu <anh.nguyen2@insa-rennes.fr> Date: Wed, 25 Jan 2023 17:25:19 +0100 Subject: [PATCH] TP --- README.md | 53 +++++++++++++++++++++++++++++++++++- images/connectapipython.PNG | Bin 0 -> 14528 bytes 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 images/connectapipython.PNG diff --git a/README.md b/README.md index 33447cf..7296943 100644 --- a/README.md +++ b/README.md @@ -231,4 +231,55 @@ Résultat attendu #### Q9. Calculer la proportion de personnes dont le solde est strictement inférieur à 1000 (pas sur pour cette question) -## Partie 2 : API Elasticsearch +## Partie 2 : Elasticsearch Client sur Python + +Pour cette partie là , on exploitera comment intéragir avec Elasticsearch sur Python. Vous pouvez utiliser IDE comme vous voulez. +**Note** : à part d'Elasticsearch, d'ici, on a également besoin de librairie pandas +#### Q1. Installer Elasticsearch, importer dans Python + +>pip3 install elasticsearch + +Dans votre script python : +>import elasticsearch +from elasticsearch import Elasticsearch + +Voir la version elasticsearch : +>print (elasticsearch.VERSION) + +D'ici, j'utilise la version 8.6.0 +#### Q2. Connecter avec le server Elasticsearch +>ELASTIC_PASSWORD = {Votre password} +client = Elasticsearch( +"https://localhost:9200", +ca_certs="path/vers/http_ca.cert", +basic_auth=("elastic", ELASTIC_PASSWORD) +) + +Il faut checker si tout va bien en lancant : + +> client.info() + +La réponse doit rassemble à cela : + + + +Vous pouvez également prendre les données qu'on a créé dans la 1ère partie : +> client.search(index='customer',body={"query": {"match_all": {}}}) +#### Q3. Traitement les données +Pour la suite de TP, nous vous donnons un dataset qui est les tweets qui ont hashtag #Farmersprotest. Dans cette question, nous avons besoin de nettoyer les données avant injecter dans Elasticsearch +#### 3.1. Lire les données au format JSON +Hint: Utiliser pandas.read_json('/path/des/données',lines=True) +#### 3.2. Filtrer +Nous n'utilisons que les tweets en Anglais et nous ne voulons pas de doublons. En plus, il n'y a que les colonnes : id, date, user, renderedContent qui nous servirons pour la suite. Renommer le champ id -> tweetID pour distinguer. La table résultant appelé raw_tweets + +Appeler la fonction head() pour voir les résultats +#### 3.3. Flatten nested champ +Nous voyons que le champ "user" est nested, essayons de créér un table à partir de ce champ. Supprimer de doublons. Nous ne gardons que les colonnes : id, location. Renommer le champ id -> userID pour distinguer. La table résultant appelé users + +Hint: Utiliser pandas.json_normalize, il faut importer avant utiliser +#### 3.4. Créer la table finale +La table finale appelé "tweets" est créé en mergent les 2 tables précédentes. + +#### Q4. Injection les données dans Elasticsearch + +## Partie 3 : Agrégation de données et visualisation dans Kibana diff --git a/images/connectapipython.PNG b/images/connectapipython.PNG new file mode 100644 index 0000000000000000000000000000000000000000..88895be5e4d721c979d8126333ee602d6409cde7 GIT binary patch literal 14528 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 SpT7<zZeG80t>}tV<o^YNz}j{I literal 0 HcmV?d00001 -- GitLab