Script python elasticsearch


(ouriel) #1

bonjour,

je suis entrain de crée un script en python pour récupérer de la base ES des nom et les IPs qui sont associé au nom,ainsi que le timestamp , le tous trié .
Le probleme est que je n'arrive pas a faire une requette adapté.
tous aide sera la bienvenue
merci.

voici mon code à ce jour

from elasticsearch import Elasticsearch
import json
es = Elasticsearch(['xxx.xxx.xxx.xxx:9200'])
res = es.search(
index='test',search_type='count',

body={ "filter": {
        "bool": {
          "must": {
            "range": {
              "timestamp": {
                "from": "2018-05-01 09:00:51.553",
                "to": "2018-06-15 09:00:51.553",
                "include_lower": "true",
                "include_upper": "true"
              }
            }
          }
        }
        },
        "aggs":{
                "all_accountname":{
                                "terms": {
                                        "field": "AccountName",
                                        }
                                },
                                "all_ip":{
                                        "terms": {
                                                 "field": "server_ip",
                                                }
                                        }
                                },
                                "sort": [
                                         {"timestamp": { "order": "desc" }
                                        }
                                        ]
                                }
)
print(res)
for i in res['aggregations']['all_accountname']['buckets']:
        for z in res ['aggregations']['all_ip']['buckets']:
                print ('noms des comptes', i['key'],'voici mon adresse',z['key'])

(Gabriel Tessier) #2

Bonjour,

Est-ce que tu peux donner plus de details, comme un exemple de données et le résultat retourné.
Et aussi formatter ton message:

from elasticsearch import ElasticSearch
...

Pour l'instant ce que je peux voir c'est que t'as 2 aggregations distincts qui retournent chacune le top 10 de tes terms.

Si tu veux la valeur de server_ip de ton AccountName faut que t'imbriques tes aggregations.


(ouriel) #3

bonjour,

merci de votre retour

2 aggregations distincte c'est pas quand je defini 2 fois "aggs"?

ci joint une capture de mon rendu.


(Gabriel Tessier) #4

yep autant pour moi... avec le formattage c'est tout de suite plus lisible :grin:

Si tu peux mettre un example de données, sur lequel tu requetes ca me permettrai de faire un test en local.


(ouriel) #5

tous est dans dans le script je peux pas partager la base!

as-tu une idée a me conseiller?

j'ai peux être une idée mais je ne serai pas le faire, c'est de parser en python afin de récupérer les données associé.

mais je préférerais le faire avec une requête ES


(Gabriel Tessier) #6

Il y'a bien un probleme d'imbrication dans ta requete, tu peux essayer avec ca?

{
  "aggs": {
    "all_accountname": {
      "terms": {
        "field": "AccountName"
      },
      "aggs": {
       "all_ip": {
      "terms": {
        "field": "server_ip"
      }
    } 
      } 
  }}, "size": 0
}

Remarque l'aggregations all_ip est dans l'accolade "all_accountname".

En local j'ai essaye de construire des donnees et j'ai le resultat suivant:

"aggregations": {
    "all_accountname": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "Banana4",
          "doc_count": 2,
          "all_ip": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "-",
                "doc_count": 1
              },
              {
                "key": "10.0.0.1",
                "doc_count": 1
              }
            ]
          }
        },
        {
          "key": "Banana",
          "doc_count": 1,
          "all_ip": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "-",
                "doc_count": 1
              }
            ]
          }
        }
     ...

Pour le compre Banana4, j'ai l'ip - et 127.0.0.1

Pour info la structure des mes documents:

POST mon_index/doc
{
  "AccountName": "Banana4",
  "server_ip": "-",
  "timestamp": "2018-06-05 13:22:22"
}

(ouriel) #7

bonjour merci de votre retour,

j'ai essaye ce que vous avez envoyé mais en vain je n'ai aucune ip qui ressort.
ci joint mon code ainsi que le résultat.

indent preformatted text by 4 spaces
 from elasticsearch import Elasticsearch
 import json
es = Elasticsearch(['xxx.xxxx.xxxx.xxxx:9200'])
res = es.search(
index='test',search_type='count',

body={ "filter": {
    "bool": {
      "must": {
        "range": {
          "timestamp": {
            "from": "2018-05-01 09:00:51.553",
            "to": "2018-06-15 09:00:51.553",
            "include_lower": "true",
            "include_upper": "true"
          }
        }
      }
    }
    },
    "aggs": {
             "all_accountname": {
                                    "terms": {
                                             "field":  "AccountName"
                                             },
                                            "aggs": {
                                                     "all_ip": {
                                                             "terms": {
                                                                    "field": "server_ip"
                                                                     }
                                                             }
                                                     }
                            }
            },
  "size": 0
 })
 print(res)
 for i in res['aggregations']['all_accountname'] ['buckets']:
         for z in i ['aggregations']['all_ip']['buckets']:
                     print ('noms des comptes',i['key'],'voici mon adresse',z['key'],"a tel jour",)

RENDU!

autre petite question : comment integre le timestamp dans ma requette ?
j'essaye avec ceci mais il me retourne rien.

   "aggs":{
                "all_histogram": {
                                                 "date_histogram": {
                                                                                   "field": "@timestamp",
                                                                                    "interval": "month"
                                                                                    }

                                                 }

(Gabriel Tessier) #8

Bonjour,

Juste une question quel version d'elasticsearch tu utilises?
Pour info search_type est dépreciée, tu peux l'enlever vur que t'as size = 0
https://www.elastic.co/guide/en/elasticsearch/reference/2.4/breaking_21_search_changes.html

Sinon dans ton body tu peux mettre query au lieu de filter ca marchera mieux (elasticsearch rajoute du cache) et plus longtemps (avec la version 6.x filter retourne une erreur).
Et derniere remarque pour la query range tu peux utiliser "gte" et "lte" au lieu de from et to et les includes, avec tous les changements ca donnerai ca:

res = es.search(
index='mon_index', # <---- ici j'ai enleve le search_type

body={ "query": { # <---- remplace le filter par query
    "bool": {
      "must": {
        "range": {
          "timestamp": {
            "gte": "2018-05-01 09:00:51.553", # <--- remplace from et to avec gte et lte
            "lte": "2018-06-15 09:00:51.553"
          }
        }
      }
    }
    }

Pour l'aggregation avec le timestamp:

 {
  "aggs": {
"all_accountname": {
  "terms": {
    "field": "AccountName"
  },
  "aggs": {
    "all_ip": {
      "terms": {
        "field": "server_ip"
      }
    },
    "all_histogram": {
      "date_histogram": {
        "field": "timestamp",
        "interval": "month"
      }
    }
  }
}
  },
  "size": 0
}

Et le script en python:

print(res)
for i in res['aggregations']['all_accountname'] ['buckets']:
  for z in i ['all_ip']['buckets']: # <--- eneleve ['aggregations']
    print ('noms des comptes',i['key'],'voici mon adresse',z['key'],"a tel jour",)
  for z in i ['all_histogram']['buckets']:
    print ('noms des comptes',i['key'],'voici ma date',z['key'],"a tel jour",)

J'ai juste enlevé la cle aggregations dans la deuxieme boucle. J'ai aussi rajouté la date.

Ci-dessous le mapping que j'ai utilise et mon jeux de donnees. Elastic version 6.2.4

PUT mon_index
{
  "settings": {
    "index": {
      "number_of_shards": "1"
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "AccountName": {
          "type": "keyword",
          "ignore_above": 256
        },
        "server_ip": {
          "type": "keyword",
          "ignore_above": 256
        },
        "timestamp": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss"
        }
      }
    }
  }
}

POST mon_index/doc
{
  "AccountName": "Banana3",
  "server_ip": "127.1.1.3",
  "timestamp": "2018-05-03 13:22:22"
}

(ouriel) #9

Bonjour ,
merci de votre retour.
apres avoir essayer je me retrouve avec cette erreur.

cela vous parle?


(Gabriel Tessier) #10

yop,
y'a une erreur de syntaxe dans la requete au niveau du "bool"...
sans la requete je peux pas dire plus.
------ EDIT ------
Ce qui serait plus pratique c'est de valider en premier que la requete fonctionne bien dans kibana ou kopf ou je ne sais quel client.
Et ensuite mettre la requete dans le code python.


(system) #11

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.