본문 바로가기

공부방/Elasticsearch

매핑 Mapping

동적 매핑

 

Elasticsearch 를 활용하면서 가장 손이 많이 가는 작업이 매핑 설정입니다.

Elasticsearch 는 동적 매핑을 지원하기 때문에 미리 정의하지 않아도 인덱스에 도큐먼트를 새로 추가하면 자동으로 매핑이 생성됩니다. 

 

만약 books 인덱스가 있다면 먼저 삭제해줍니다.

 

DELETE books

 

인덱스가 없는 상태에서 다음의 도큐먼트를 books 인덱스에 입력 해 보겠습니다.

 

PUT books/_doc/1
{
  "title": "Romeo and Juliet",
  "author": "William Shakespeare",
  "category": "Tragedies",
  "publish_date": "1562-12-01T00:00:00",
  "pages": 125
}

 

mapping 정보는 RDBMS에서 schema 라고 보면 됩니다.

 

Setting과 Mapping 정보를 같이 보려면 아래 명령어를 사용하면 됩니다. (GET index 이름)

 

GET books

 

Mapping 정보를 확인하려면 아래 명령어를 사용하면 됩니다.

 

GET books/_mapping

 

title, author, category 필드들은 textkeyword타입으로,

pages 필드는 long 타입으로,

publish_date 필드는 date 타입으로 자동 지정 된 것을 확인할 수 있습니다.

 

Elasticsearch 의 매핑이 동적으로 생성 될 때는 필드의 값을 보고 타입을 예상하는데, 항상 그 필드가 포함될 수 있는 가장 넓은 범위 형태의 데이터 타입을 선택합니다. Elasticsearch 의 매핑이 동적으로 생성 될 때는 필드의 값을 보고 타입을 예상하는데, 항상 그 필드가 포함될 수 있는 가장 넓은 범위 형태의 데이터 타입을 선택합니다.

 

필드 추가

이미 만들어진 매핑에 필드를 추가하는 것은 가능하지만 기존에 있는 필드를 바꿀수는 없습니다.

 

content라는 필드를 추가하고

type은 text로 지정해 줍니다.

 

PUT books/_mapping
{
  "properties": {
    "content": { 
      "type": "text"      
    }
  }
}

 

Keyword 타입

 

필드 타입으로 지정할 수 있는 것 중에 "keyword" 라는 타입이 존재합니다.

"keyword" 타입을 공부하기 위해 아래 예시를 살펴봅시다.

먼저 우리가 만들었던 books 인덱스의 mapping을 살펴봅시다. 

 

title 필드는 text 타입으로 되어있고

title.keyword 필드는 keyword 타입으로 되어있는 것을 확인할 수 있습니다.

 

(title 필드 안에 keyword 필드가 존재 하는데 이것이 멀티 필드 형식입니다.)

 

// GET books/_mapping

{
  "settings": {
    "analysis": {
      "analyzer": {
        "engram_a": {
          "tokenizer": "standard",
          "filter": [ "lowercase", "engram_f" ]
        }
      },
      "filter": {
        "engram_f": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 5
        }
      },
      "normalizer": {
        "norm_low": {
          "type": "custom",
          "filter": [ "lowercase", "asciifolding" ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "boost": 2,
        "fields": {
          "keyword": {
            "type": "keyword",
            "normalizer": "norm_low"
          }
        }
      },
      "author": {
        "type": "text",
        "analyzer": "engram_a",
        "search_analyzer": "standard",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "synopsis": {
        "type": "text",
        "fielddata": true
      },
      "category": {
        "type": "keyword"
      },
      "content": {
        "type": "text",
        "index": false
      }
    }
  }
}

 

title 필드의 타입은 text이기 때문에 기본적으로 text는 단어 단위로 역색인이 될 것이고 Romeo, Juliet 각각 검색해도 검색 결과를 확인할 수 있습니다.

 

GET books/_search
{
    "query" : {
    	"match": {
        	"title": "Juliet"
        }
    }
}

 

title 안에 keyword 필드가 존재하는 이 keyword 필드의 타입은 keyword 입니다.

필드가 keyword  타입일 경우 나눠지지 않고 문장 그대로 저장이 되는데 보통은 집계(aggregation) 또는 정렬(sorting)에 사용할 문자열 필드를 keyword 타입으로 지정합니다

 

title.keyword를 검색할때는 문장 전체를 검색해야 합니다.

"Romeo and Juliet" 으로 검색하면 검색 결과를 확인할 수 있겠지만

Romeo와 Juliet으로 각각 검색하면, 검색 결과를 확인할 수 없습니다.

 

GET books/_search
{
    "query" : {
    	"match": {
        	"title.keyword": "Romeo and Juliet"
        }
    }
}