ElasticSearch 데이터 모델링

윤들윤들·2021년 2월 28일
0
post-thumbnail

데이터베이스에 테이블에 어떠한 속성이 들어갈것인지에 대한 정보를 정의하는것이 중요한 만큼
ElasticSearch에서도 각 컬럼에 어떠한 데이터가 들어갈지 데이터타입을 정의하는것은 매우 중요합니다.

앞에서 확인한 스키마리스 기능을 통해 자동으로 컬럼에 데이터 타입을 매핑하여 자동으로 생성되기도 하지만 스키마리스 방식은 실수로 잘못된 타입이 지정될수 있습니다.

어떠한 경우에 이러한 문제가 될지 예제로 확인하겠습니다.

# Document 1 
{
	movieCode : "123456789"
    movieName : "해리포터와 마법사의돌"
}

# Document 2
{
	movieCode : "HP0002"
    movieName : "해리포터와 비밀의 방"
}

다음과 같은 예제로 설명해보겠습니다.

첫번째 Document 1을 매핑 정보 없이 색인한다고 가정하겠습니다.
그렇다면 색인이 될때 movieCode는 숫자타입, movieName은 문자타입 으로 매핑될것입니다.

이번에는 두번째 Document 2를 매핑정보 없이 색인을 해보겠습니다.
정상적으로 등록될것같지만 실제로 는 색인이 불가능 합니다.

왜냐하면 Document2의 movieCode 는 문자타입이기 때문에 숫자 타입에 매핑할 수 없기 때문입니다.

만약 movieCode가 문자인 데이터가 먼저 색인되었다면 숫자데이터가 들어있는 movieCode는 문자로 취깁되어 색인이 가능할 것입니다.

ElasticSearch의 특성상 생성된 매핑 타입은 변경할 수 없습니다. 따라서 이렇게 잘못 만듥경우 인덱스를 삭제한 후 다시 생성하거나 매핑을 다시 정의해야합니다.

따라서 매핑 인덱스를 만들기 전에 충분히 고려한 상태에서 만드는게 좋아보입니다.


💡 매핑 인덱스 만들기

테스트용 인덱스를 만들어 학습해 보겠습니다.

/users 인덱스를 만들어보겠습니다

매핑 이름필드 명필드 타입
인덱스 키userKeykeyword
이름_국문userNametext
이름_영문userNameEntext
나이userAgeinteger
이메일userEmailkeyword

간단하게 다음처럼 설정하고 테스트 해보도록 하겠습니다.

이름 국문과, 이름 영문같은 경우는 검색이 되도록 text타입으로 정의했습니다. 나머지는 그냥 integer나 keyword로 지정했습니다.

PUT /users
{
  "mappings": {
    "properties": {
      "userKey" : {
        "type": "keyword"
      },
      
      "userName" : {
        "type": "text"
      },
      
      "userNameEn" : {
        "type": "text"
      },
      
      "userAge" : {
        "type": "integer"
      },
      "userEmail" : {
        "type": "keyword"
      }
    }
  }
}

위와 같이 실행하여 users 인덱스를 생성하였습니다.


💡 생성된 인덱스 확인

위에서 인덱스를 생성하였으니 제대로 생성이 되었는지 확인해 보겠습니다.

GET /users/_mapping
{}

# 실행 결과
{
  "users" : {
    "mappings" : {
      "properties" : {
        "userAge" : {
          "type" : "integer"
        },
        "userEmail" : {
          "type" : "keyword"
        },
        "userKey" : {
          "type" : "keyword"
        },
        "userName" : {
          "type" : "text"
        },
        "userNameEn" : {
          "type" : "text"
        }
      }
    }
  }
}

💡 매핑 파라미터

매핑 파라미터는 색인될 필드의 데이터를 어떻게 저장할것인지에 대한 다양한 옵션을 제공합니다.
너무 다양하지만 제 기준으로 필요하다고 생각한것만 추려보았습니다..


☝ analyzer

analyzer 파라미터는 해당 필드의 데이터를 분석하겠다는 의미의 설정입니다.
색인과 검색 시 지정한 분석기로 형태소 분석을수행합니다.
text 타입의 필드는 analyzer 매핑 파라미터를 기본적으로 사용해야 합니다. 설정을 하지 않는다면 기본적으로 Standard Analyzer형태소로 분석을 진행합니다.


☝ normalizer

normalizer 파라미터는 term query에 분석기를 사용하기 위해 사용된다.
keyword 타입의 경우에는 원문을 기준으로 문서가 색인되기 때문에 영어의 대소문자가 다르면 서로 다른 문서로 인식하게 되지만 , normalizer를 통해 분석기에 asciifolding과 같은 필터를 사용하면 같은데이터로 인식하게 됩니다.


☝ coerce

색인시 자동 변환을 허용할지에 대한 유무 입니다.
coerce를 설정하였다면 "1000" 이라는 숫자 형태의 문자열이 integer 타입의 필드에 들어온다면 자동으로 형변환을 하여 integer로 색인을 합니다.


☝ copy_to

매핑 파라미터를 추가한 필드의 값을 지정한 필드로 복사한다.
keyword 타입의 필드에 copy_to 매핑 파라미터를 사용하여 다른 필드로 값을 복사하면 복사된 필드에서는 text타입을 지정해 형태소 분석을 할 수 있다.

따로 설명은 없이 코드로 대체하겠습니다.

#Users_copy

PUT /users_copy
{
  "mappings": {
    "properties": {
      "userKey" : {
        "type": "keyword"
      },
      
      "userName" : {
        "type": "keyword",
        "copy_to": "userNameSearch"
      },
      
      "userNameEn" : {
        "type": "keyword",
        "copy_to": "userNameSearch"
      },
      
      "userAge" : {
        "type": "integer"
      },
      "userEmail" : {
        "type": "keyword"
      },
      "userNameSearch" : {
        "type": "text"
      }
    }
  }
}

POST /users_copy/_doc/1
{
  "userKey" : "users_00001",
  "userName" : "최윤진",
  "userNameEn" : "Choi Yun Jin",
  "userAge" : 29,
  "userEmail" : "zzdd1558@gmail.com"
}

GET /users_copy/_search
{
  "query": {
    "match": {
      "userNameSearch": "최윤진 Choi Yun Jin"
    }
  }
}

☝ enabled

enabled 파라미터는 검색 결과에는 포함하지만 색인은 하고 싶지 않을 경우에 사용합니다.
이 파라미터는 메타 성격의 데이터에게 사용합니다.
게시판 데이터를 제목과 글만 색인하고 날짜같은 메타데이터들은 색인하고 싶지 않을 경우입니다.
색인을 원하지 않는 컬럼들에는 enabled 파라미터를 false로 설정해주면 _source에는 검색이 되지만 색인을 하지는 않습니다.


search_analyzer

기본적으로 색인과 검색시 같은 분석기를 사용합니다. 만약 다른 분석기를 사용하고 싶은경우 search_analyzer를 설정하여 사용할 분석기를 별도로 지정할 수 있다.

이 외에도 다양한 파라미터 들이 존재합니다.
하지만 글로 표현하는데 한계가 있어 제 생각 기준으로 사용할만한 것들을 추려서 정리하였습니다.

글을 보시고 이 외에도 중요한 내용에대해 적어주시면 공부하여 정리해보도록 하겠습니다!

profile
Front&BaackEnd를 재미있게 공부하고싶은 개발자 YundleYundle

0개의 댓글