
Elasticsearch가 설치되어 있는 환경에서, Python으로 간단한 질의를 해 본 스크립트이다.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
from  elasticsearch import Elasticsearch
host = '150.19.5.30'
port = '9200'
target = 'http://{}:{}'.format(host,port)
#print(target)
es = Elasticsearch( [{'host':host, 'port':port}])
docs = es.search(index='skt_app_vdi_file-20171123', filter_path=['hits.hits._*'])
#len(docs['hits']['hits'])
docs['hits']['hits'][1]['_source']
Elasticseach 라이브러리를 import 하고, es를 할당하여 index 및 document를 얻어 온다.
document를 가져오면, JSON형태가 상당히 번거로운 구조를 가지고 있다.
따라서, 원하는 본문을 얻기위해서, docs['hits']['hits'] 후 부터 본격적인 검색 결과라 하겠다.
hits는 elastic에서 Keyword 검색에 유사성을 나타내고 있는 score 값이다.
기왕 Python 으로 엘라스틱을 사용해본 김에 클래스로 만들어 보자.
(사실 그냥 JSON형태로 묶어서 rest 로 날려주는게 더 나을 지도 모른다.)
class MyElastic():
    def __init__(self, index, hosts, ports, size=1000) :
        self.index = index
        self.host = hosts
        self.ports = ports
        self.body = ""
        self.aggs = None
        self.res = None
        self.total = 0
        self.df = None
        self.s = None
        self.cols = None
        self.q = None
        
        server_list = [ {'host':x, 'port':y}  for x,y in zip(hosts,ports) ]
        self.es = Elasticsearch( server_list, size=size )        
        self.s = Search(index = index).using(self.es)
           
    def search(self, q, nSize=1000, iFrom=0):
        s = self.s
        s = s.query(q)
        
        s = s[iFrom : iFrom + nSize]
        res = s.execute()
        
        self.total = res.hits.total        
        self.q, self.s, self.res = q,s, res
    
    def search_wild(self, f="emp_id", v="*", nSize =1000 ):
        s = self.s       
        q_dict = {"query":{"wildcard":{str(f)+".keyword": v}}, "size": nSize }
        s = s.query(Q("match_all"))
        s = s.update_from_dict(q_dict)
        res = s.execute()
        
        self.total = res.hits.total        
        self.s, self.res = s, res    
       
        
    def search_from_body(self, body):
        return None
    
    def get_by_id(self, id, s_type="match"):
        q = Q(s_type, emp_id=id)
        self.search(q)
        self.df = self.to_df(self.res)
        return self.df
        
        
    def to_df(self, res):
        aDict = [ x['_source'] for x in res.hits.hits]
        df = pd.DataFrame(aDict)        
        return df
    
    def get_cols(self,res):
        if self.total!=0:
            cols = list(res.hits.hits[0]['_source'].keys())
            return cols
        else:
            return None
Pandas로 엘라스틱 서치 검색결과를 연동해 서 사용해 볼 수 있다.
import pandas as pd
arr_dict = [ x['_source'] for x in docs['hits']['hits'] ]
df_raw = pd.DataFrame(arr_dict)
print("Shape:", df_raw.shape)
print("columns:", df_raw.columns)
df_raw.head(3)
plt.rcParams["font.family"] = 'New Gulim'   # 한글 폰트 지정
g = sns.countplot(data=df_raw, x='request')
g.set_xticklabels(g.get_xticklabels(), rotation = 30)
plt.show()
df_g = df_raw.groupby(['client_ip','portdesc'])['emp_id'].count()
hmap = df_g.unstack(['client_ip']).fillna(0).astype('int64')
fig, ax = plt.subplots(figsize=(15,10))
g = sns.heatmap(hmap, annot=True, fmt='d', linewidths=.5, vmin=0, vmax=100, ax=ax)
g.set_xticklabels(g.get_xticklabels(), rotation = 30)
plt.show()
| ADB와 Logcat 이용하여 스마트폰 디버깅 (2) | 2020.03.16 | 
|---|---|
| 자녀 IT교육 - 자녀와 게임 만들어 Play Store 출시하기 (8) | 2020.03.15 | 
| RESTful API with Flask (0) | 2020.03.10 | 
| docker-compose.yml 파일 설명 정리 (작업중) (0) | 2020.03.10 | 
| Heroku 사용기 (0) | 2020.03.09 | 
댓글 영역