kok202
엘라스틱 서치 String이 사라진 이유

2019. 4. 2. 19:58[정리] 데이터베이스/[NoSQL] ElasticSearch

관련 포스팅 https://www.elastic.co/blog/strings-are-dead-long-live-strings

 

Elasticsearch replaces string type with two new types text and keyword.

On using text types for full text search and keyword type for keyword search in Elasticsearch 5.0.

www.elastic.co

 

 

 

일반적으로 Elastic search에서 String 을 검색하는 방법은 크게 2개이다.

1. full-text-search : new york을 검색할 때 new, york 과 같이 개별적인 토큰을 이용해서 검색하는 방법

2. keyword-search : new york을 검색할 때 'new york'을 전부 다 줘서 검색하는 방법

 

그리고 두 use case에 대하여 사용자는 index 옵션을 다르게 줬어야했다.  (전문 검색의 경우 index를 analyzed라고 설정해두고 키워드 검색의 경우 index를 not_analyzed로 설정해줬다.)

 

그런데 같은 필드 타입을 두개의 use case로 사용하는 것이 부적절해 보였다. 

심지어 string에 들어가는 어떤 옵션은 하나의 use case 에서만 동작하는 경우도 존재했다.

ex1. position_increment_gap 옵션은 analyzed 에서만 제대로 동작했다.

ex2. ignore_above 옵션은 analyzed에서 적용되는지 명확하지 않다.

 

이러한 문제점들을 피하기 위해 String을 text와 keword로 분리하였다.

차이점 요약 : https://stackoverflow.com/questions/52845088/difference-between-keyword-and-text-in-elasticsearch

city 필드가 text 타입일 경우 검색할 때 new, york 만 검색해봐도 new york 이 검색된다.

city 필드가 keyword 타입일 경우 검색할 때 new york 을 전부 던져줘야 new york이 검색된다.

 

그런데 분리하고 나니까 또 다른 문제점이 생겼다. 무엇을 다이나믹 맵핑(맵핑 파일이 없을 때 자동 맵핑)의 default로 할 것인가.

text로 해야하는가? keyword로 해야하는가? 

- keyword 로 할 경우 검색할 때마다 전체 키워드를 다 던져줘야하므로 범용성이 떨어진다. 우리가 생각하는 검색엔진은 text 쪽이 가깝다.

- text 로 할 경우 통계할 때 문제가 생긴다. 예를들어 city 라는 필드가 데이터 타입이 text라고 생각해보자. city 를 통계 할 때 데이터 값이 new york 일 경우 new 에대한 카운트 하나 추가 york 에대한 카운트가 하나 추가된다. 이는 부자연스럽다. 통계에 있어서 만큼은 keyword 처럼 'new york' 에대한 카운트만 하나 추가 되야한다.

 

그래서 다이나믹 맵핑의 기본 값은 text와 keyword를 섞어 쓰는 것으로 하자 로 결정됬다.

{
  "city": {
    "type" "text",
    "fields": {
      "keyword": {
        "type": "keyword",
        "ignore_above": 256
      }
    }
  }
}

 

이렇게하면 type이 text 이므로 full text search 도 가능하고 city.keyword를 이용해서 통계도 낼 수 있다.