본문 바로가기
ElasticSearch & OpenSearch

[ElasticSearch] _script 를 사용한 sort

by yonikim 2022. 5. 5.
728x90

 

Painless 란?

ElasticSearch를 사용하다보면 Elastic Query DSL이나 Lucene Query, KQL (Kibana Query Language) 등으로는 원하는 대로 데이터를 조회 및 가공하기 어려운 상황 등이 발생한다.

이런 경우 Painless 라는 Elasticsearch 전용 Script 언어를 이용해서 문제를 해결할 수 있다.

Painless는 ElasticSearch 전용으로 만들어진 단순하고 안전한 스크립트 언어로, ElasticSearch에서 inline scripts와 stored scripts에 기본으로 사용된다.

 

 


_script 를 사용한 sort

ElasitcSearch 의 경우 문자열 정렬 기준이 `숫자 -> 영문 -> 한글` 순인데, 기획 쪽에서 브랜드명 디폴트 정렬 순서를 `한글 -> 영문 -> 숫자` 로 해달라고 요청했다. 이를 해결하기 위해서는 _script 를 사용할 수 밖에 없었다.

정규식을 이용하여 정렬 점수를 매기는 방법으로 진행했다. 

 

 

브랜드명이 숫자로 시작하면 정렬 순서를 3위로,

def number = /^([0-9])+/.matcher(doc['name.keyword'].value);
if (number.find()) { sortOrder = 3 };

 

브랜드명이 영문으로 시작하면 정렬 순서를 2위로, 

def english = /^([A-Za-z]+)/.matcher(doc['name.keyword'].value);
if (english.find()) { sortOrder = 2 };

 

그 외에는 정렬 순서를 1위로 설정해주는 script 다.

 

 

전체 쿼리

GET brand/_search
{
   "from":0,
   "size":10,
   "sort":[
      {
         "_script":{
            "type":"number",
            "script":{
               "source":"def number = /^([0-9]+)/.matcher(doc['name.keyword'].value); def english = /^([A-Za-z]+)/.matcher(doc['name.keyword'].value); int sortOrder = 0; if (number.find()) {sortOrder = 3} else if (english.find()) {sortOrder = 2} else {sortOrder = 1}  sortOrder;"
            },
            "order":"asc"
         }
      },
      {
         "name.keyword":{
            "order":"asc"
         }
      }
   ]
}

 

728x90