text는 유연한 검색이 필요할 때 사용한다고 얘기했다. 반면에 keyword는 정확한 검색이 필요할 때 사용한다고 했다. 상품 카테고리와 이름 필드에 저장된 필드 값에 대해 키워드로 검색할 때는 유연하게 검색되게 하고 싶고, 정확한 비교를 통해 특정 카테고리를 기준으로 필터링을 하고 싶을 수 있다. 즉, text 타입과 keyword 타입을 동시에 사용하고 싶은 경우이다. DELETE /products PUT /products { "mappings": { "properties": { "name": { "type": "text", "analyzer": "nori" }, "category": { "type": "text", "analyzer": "nori" } } } }
POST /products/_doc { "name": "삼성 세탁기", "category": "특수 가전제품" }
name, category을 활용해 유연하게 검색하고 싶을 때]GET /products/_search { "query": { "multi_match": { "query": "가전", "fields": ["name", "category"] } } }
특수 가전제품 카테고리의 상품만 검색하고 싶을 때]GET /products/_search { "query": { "term": { "category": "특수 가전제품" } } }
category의 데이터 타입을 설정할 때 text 타입과 keyword 타입을 둘 다 선언해야 한다. 그 방법을 알아보자. DELETE /products PUT /products { "mappings": { "properties": { "name": { "type": "text", "analyzer": "nori" }, "category": { "type": "text", "analyzer": "nori", "fields": { "raw": { // 서브 필드명 (다른 이름으로 설정해도 됨) "type": "keyword" } } } } } }
category 필드에 하나의 데이터를 삽입하더라도 text, keyword 타입의 형태로 나눠서 보관하게 된다. POST /products/_doc { "name": "삼성 세탁기", "category": "특수 가전제품" }
text 타입은 토큰으로 분리해서 저장하지만, keyword 타입은 값 자체를 통째로 저장한다. 그래서category에 특수 가전제품이라는 값을 삽입했을 때 아래와 같이 저장된다. category (text 타입) | category.raw (keyword 타입) |
특수 | 특수 가전제품 |
가전 | ㅤ |
제품 | ㅤ |
POST /products/_analyze { "field": "category", "text": "특수 가전제품" } POST /products/_analyze { "field": "category.raw", "text": "특수 가전제품" }
name, category을 활용해 유연하게 검색하고 싶을 때]POST /products/_search { "query": { "multi_match": { "query": "가전", "fields": ["name", "category"] } } }
특수 가전제품 카테고리의 상품만 검색하고 싶을 때]POST /products/_search { "query": { "term": { "category.raw": "특수 가전제품" } } }