inverted index란#
- 문서에 포함된 문자열을 어떤 기준으로 단어로 나누는데 이렇게 나뉜 단어들을 토큰이라고 부른다.
- 이렇게 토큰을 만들어내는 과정을 토크나이징이라고 부른다.
- 토큰을 기준으로 저장된 문서를 아래와 같이 저장하는데 이것을 inverted index라고 부른다.
- analyzer 종류 마다 토크나이징 결과가 달라진다.
analyzer 살펴보기#

- analyzer를 구성할 때는 tokenizer를 필수로 명시해야 하며 하나의 tokenizer만 설정할 수 있다.
- character filter와 token filter는 필요하지 않은 경우 기술하지 않거나 여러 개를 기술할 수 있다.
- character filter: analyzer로 들어온 문자열을 변형한다.
- 예시:
<
, >
, !
등과 같은 의미 없는 특수 문자들을 제거한다거나 HTML 태그들을 제거하는 등 문자열을 구성하고 있는 문자들을 특정한 기준으로 변경한다.
- tokenizer: 일정한 기준에 의해 문자열을 n개의 토큰으로 나눈다.
- token filter: 생성한 토큰들을 변형한다.
- 예시: lowercase token filter는 토큰을 전부 소문자로 바꾼다.

- standard tokenizer는 unicode standard annex 라는 룰에 따라 문자열을 분리한다.
- standard token filter는 실질적으로는 아무런 작업을 하지 않지만, 향후 개발되는 버전에서 필터링 기능을 사용하게 될 경우를 대비하여 포함되어 있다.
analyzer와 검색 관계#
- analyzer를 통해 생성된 토큰들이 inverted index에 저장되고, 검색할 때는 이 inverted index에 저장된 값을 바탕으로 문서를 찾는다.
text
타입의 기본 analyzer는 standard analyzer
이고 keyword
타입의 기본 analyzer는 keyword analyzer
이다.standard analyzer
는 아래와 같이 단어 단위로 토큰을 만든다.- keyword analyzer는 아래와 같이 문자열이 나뉘어지지 않고 통으로 하나의 토큰을 구성하고 있다. 그렇기 때문에
keyword
타입은 일부 단어로 검색이 되지 않는다. - analyzer에 따라서 검색 결과와 품질이 달라지기 때문에 사용자의 검색 니즈를 잘 파악해서 그에 맞는 analyzer를 설정하느 것이 중요하다.
- analyzer는 운영 중에 동적으로 변경할 수 없기 때문에 analyzer를 바꿀 경우 인덱스를 새로 만들어서 재색인해야 한다는 점을 기억하자.
Search API#
- 검색을 하기 위해서는 아래와 같이 POST 요청으로 쿼리를 보낼 수 있다.
- RequestBody에는 다양한 옵션이 들어갈 수 있다.
- from/size의 기본값은 각각 0/10 이다.
- sort 옵션은 text가 아닌 keyword나 integer와 같이 not analyzed가 기본인 필드를 기준으로 해야한다.
- 특정 검색 쿼리의 스코어를 높이거나 낮추고 싶을 때
boost
옵션을 활용하면 검색 결과로 나온 스코어를 스코어를 대상으로 boost
옵션에 설정된 값을 곱한 값이 스코어로 지정딘다.- match 쿼리를 사용할 때는 query 옵션을 사용하고, term 쿼리르 사용할 때는 value 옵션을 사용해야된다.


scroll
옵션을 사용하면 새로운 문서가 인입된다고 해도 scroll id가 유지되는 동안에는 검색 결과가 바뀌지 않는다. 그래서 scroll 옵션은 검색 결과가 동일하게 유지되어야 하는 paginzation, 혹은 대량의 배치 작업에 주로 활용한다.Scroll_id
유지 기간은 노드의 힙 메모리에 영향을 주기 때문에 지나치게 길게 설정하면 Out Of Memory 에러를 발생시킬 수 있다. 사용자의 검색 패턴을 기반으로 적당한 값으로 설정해 주어야 한다.
Query DSL이란#
- 검색 쿼리는 Query DSL이라 불리며 크게 Query Context와, Filter Context로 분류한다.
- Query context: Full text search를 의미하며, 검색어가 문서와 얼마나 매칭되는지를 표현하는 score라는 값을 가진다.
- FIlter context: 검색어가 문서에 존재하는지 여부를 Yes나 No 형태의 검색 결과롤 보여준다. score 값을 가지지 않는다.
Query Context#

match 쿼리#
- match 쿼리는 검색어로 들어온 문자열을 analyzer를 통해 분석한 후 inverted index에서 해당 문자열의 토큰을 가지고 있는 문서를 검색한다.
- 문서의 해당 필드에 설정해 놓은 analyzer를 기본으로 사용하며, 별도의 analyzer를 사용할 때는 직접 명시해 주면 된다.
match_phrase 쿼리#
- analyzer를 통해 생성된 토큰들의 순서를 고려한다.
multi_match 쿼리#
- 두 개 이상의 필드에 match 쿼리를 날릴 수 있다.
- 두 필드에서 모두 match가 일어나야되는 것은 아니고, 하나만 만족하면 된다.

query_string 쿼리#
- and와 or 같은 검색어 간 연결이 필요한 경우에 사용한다.
- query_string 쿼리로 와일드카드 검색을 할 수도 있다.
- 와일드카드 검색은 검색 성능에 좋지 않기 때문에 경우에 따라서는 다른 쿼리로 수정해서 사용하는 것이 좋다.

Filter Context#

term 쿼리#
term
쿼리는 analyze를 하지 않기 때문에 당연히 대소문자를 구분한다.- 보통
text
타입의 필드를 대상으로 할 때는 term
쿼리보다 match
쿼리를 사용하는 것이 일반적이다.
terms 쿼리#
- 둘 이상의
term
을 검색할 떄 사용하는 쿼리이며, 다수의 단어를 한 번에 검색할 때 사용한다.
range 쿼리#
- 범위를 지정하여 특정 값의 범위 이내에 있는 경우를 검색할 때 사용한다.

wildcard 쿼리#
- text 필드가 아닌 keyword 타입의 쿼리에 사용해야 한다.
- wildcard query는 모든 inverted index를 하나씩 확인하기 떄문에 검색 속도가 매우 느리다.

bool query를 이용해 쿼리 조합하기#
- bool query에서 사용할 수 있는 항목
must
, should
는 Query Context에서 실행된다.filter
, must_not
은 Filter Context에서 실행된다.
- bool query는 Query/Filter Context를 혼합해서 사용할 수 있다.
- filter context에 포함되는 쿼리들은 filter 절에 넣는 것이 좋다.
- must 절에 포함시켜도 동일한 결과가 나오지만, filter context들이 socre를 계산하는 데 활용되기 때문에 불필요한 연산이 들어가서 검색 속도가 느려진다.
should
절은 minimum_should_match
라는 옵션을 제공한다.minimum_should_match
옵션은 should 항목에 포함된 쿼리 중 적어도 설정된 수치만큼의 쿼리가 일치할 때 검색 결과를 보여주는 옵션이다.
should
절은 검색을 통해 문서의 스코어를 올려줄 때 사용할 수 있다.- 따라서
minimum_should_match
옵션이 필수는 아니다. 
comments powered by