Elasticsearch ES|QL

ES|QL이 필요한 이유

Elasticsearch는 기존에도 다양한 언어들을 지원했습니다.

Dev Tools의 콘솔, Rest API 호출에 사용하는 queryDSL,
Kibana 내에서의 간단한 검색을 위한 KQL,
Pipeline, Runtime Field 등의 구성을 위한 Painless,
그 외에도 EQL, SQL, Canvas/Timelion 등
다양한 분야에 사용할 수 있도록 많은 언어를 지원합니다.

그럼에도 ES|QL이 등장한 것은,
이제 Elasticsearch의 쓰임새가 전문 검색을 넘어,
로그 탐색, 위협 헌팅, 리포팅, 알림, 사용자 지정 처리 등의 분야에 사용되기 때문입니다.

사용자들에게 외부 시스템으로 값비싼 전송을 할 필요가 없는
단일되고 통합된 방식으로 Elasticsearch에 접근할 수 있도록 한
보다 직관적인 언어가 바로 ES|QL입니다.

ES|QL의 특징

ES|QL은 파이프( | )를 사용해 단계별 방식으로 데이터를 조작하고 변환합니다.

한 작업의 출력 이후 다음 작업의 입력으로 이어지는 일련의 작업을 구성할 수 있어,
기존의 언어로는 어렵던 복잡한 데이터 변환과 분석이 가능합니다.


ES|QL은 단순한 언어 그 이상입니다.

ES|QL의 기능, 성능 요구사항을 달성하기 위해 Elasticsearch는 완전히 새로운 컴퓨팅 아키텍처를 구축했습니다.

ES|QL의 검색, 집계, 변환 기능은 기타 언어로 바뀌지 않고, 자체 내에서 직접 실행되기에 매우 뛰어난 성능으로 다양한 용도에 사용할 수 있습니다.

ES|QL 사용하기

Console (API)

Dev Tools의 콘솔에서 ES|QL을 사용할 수 있습니다.

ES|QL query의 기본 API 형식은 다음과 같습니다.





API의 """ ... """ 내에 ES|QL query를 입력 후 실행합니다.




POST /_query?format=txt

{

  "query": """


  """
}

POST /_query?format=txt

{

  "query": """

     FROM sample_data

  """
}

Kibana Discover

Kibana의 Discover 메뉴 내에서 ES|QL을 사용할 수 있습니다.

Discover 메뉴 내의 Data View 선택 부분에서 Try ES|QL을 클릭합니다.

검색 대상 데이터에 timestamp가 포함되어 있는 경우, 우측 상단의 Time Filter를 확인 후 검색 범위에 맞게 조정합니다.

상단의 Query Bar에 ES|QL query를 입력해 검색을 진행할 수 있습니다.
더 쉽게 query를 작성할 수 있도록 각 명령어나 함수의 자동 완성 기능을 제공합니다.

Query 결과에 따라서 상단에 해당 결과에 맞는 시각화를 제공합니다.
시각화 패널 우측 상단의 Save, Edit 버튼을 통해 해당 시각화를 저장, 수정하여 Visualization 패널로 내보낼 수 있습니다.

ES|QL 기초 문법

Source Command

각 ES|QL 쿼리는 Source Command로 시작합니다.
Source Command는 일반적으로 Elasticsearch의 데이터를 바탕으로 한 테이블을 생성합니다.

Source Command에는 FROM 외에도 ROW, SHOW가 있으며,
자세한 설명은 링크에서 확인 가능합니다.

FROM kibana_sample_data_flights

Processing Command

Source Command 뒤에는 파이프 문자( | )로 구분된 Processing Command가 올 수 있습니다.
Processing Command는 행과 열을 추가, 제거, 수정하여 테이블을 변경합니다.

예시로, LIMIT 명령어를 통해 반환되는 행들의 수를 지정할 수 있습니다.

FROM kibana_sample_data_flights

| LIMIT 3

SORT 명령어를 통해 하나 이상의 열을 기반으로 행을 정렬할 수 있습니다.

FROM kibana_sample_data_flights

| SORT AvgTicketPrice DESC

WHERE 명령어를 통해 데이터 쿼리를 진행합니다.

FROM kibana_sample_data_flights

| WHERE AvgTicketPrice < 1000

WHERE과 함께 LIKE 연산자를 사용하면 Wildcard 쿼리가 가능합니다.

FROM kibana_sample_data_flights

| WHERE Dest LIKE "London*"

그 외에도
KEEP, DROP 등의 명령어로 테이블의 열을 유지, 삭제하거나
ENRICH 명령어로 elasticsearch의 인덱스 데이터를 테이블에 enrich 하거나,
DISSECT, GROK 명령어로 데이터를 가공할 수 있습니다.
자세한 Processing Command에 대한 설명은 이 링크에서 확인할 수 있습니다.

명령어 조합

파이프문자( | )로 구분하여 Processing Command를 연결할 수 있습니다.
각 Processing Command는 이전 라인의 출력 테이블에서 작동합니다.
ES|QL의 쿼리 결과는 마지막 Processing Command에 의해 생성된 테이블입니다.

열 추가

EVAL 명령어를 사용해 계산된 값을 테이블의 열로 추가할 수 있습니다.

항공권 평균 가격을 원화로 확인하기 위해 AvgTicketPriceKr 열을 생성


EVAL 명령어는 Function을 지원합니다.
Function에 대한 자세한 설명은 이 링크에서 확인할 수 있습니다.

비행 소요 시간을 소수점 아래 한 자리까지 시간 단위로 표현하기 위해
ROUND 함수를 사용

FROM kibana_sample_data_flights 

| EVAL AvgTicketPriceKr = AvgTicketPrice * 1300



FROM kibana_sample_data_flights 

| EVAL FlightTimeHourApprox = ROUND(FlightTimeMin / 60, 1)

집계

ES|QL을 사용해 집계를 수행할 수 있습니다.
STATS ... BY 명령어를 통해 통계를 계산합니다.

비행 거리 중간값 집계


STATS 명령어 한 줄에서 여러 번 집계할 수 있습니다.

비행 거리 중간값, 최대값 집계



BY를 사용해 선택한 열을 기준으로
집계를 Grouping 할 수 있습니다.

항공사별 비행 거리 중간값 집계



FROM kibana_sample_data_flights 

| STATS median_distance_kilometers = MEDIAN(DistanceKilometers)

FROM kibana_sample_data_flights 

| STATS median_distance_kilometers = MEDIAN(DistanceKilometers)

      , max_distance_kilometers = MAX(DistanceKilometers)



FROM kibana_sample_data_flights 

| STATS median_distance_kilometers = MEDIAN(DistanceKilometers) BY Carrier

출처, 참고 문서

LinkedIn

ⓒ 이동훈 (Lee Donghoon)