ElasticSearch Index생성 및 주의할내용

윤들윤들·2021년 2월 16일
2
post-thumbnail

ElasticSearch는 RESTful 방식의 API를 제공합니다. 이를 통해 JSON기반으로 통신을 합니다.
ElasticSearch를 설치하고 실행하거나 설정파일을 보면 알겠지면 , 기본적으로 9200번 Port를 사용합니다.

ElasticSearch는 아래와 같은 API들을 제공합니다.

  • 인덱스 관리 API : 인덱스 관리
  • 문서 관리 API : Document의 추가/삭제/수정
  • 검색 API : Document 조회
  • 집계 API : Document 통계

ElasticSearch를 실제로 사용하면서용어가 헷갈리는 경우가 있었습니다. index , indices, indexing였습니다.
index는 색인된 데이터를 의미합니다.
indexing는 색인하는 과정을 의미합니다.
indices는 매핑 정보를 저장하는 논리적인 데이터 공간을 의미합니다.

해당 포스팅에서의 인덱스라는 말은 indices를 번역하여 사용한다고 가정하겠습니다.


💡 스키마리스 (Schemaless) 란 ?

index를 생성하기에 앞서 스키마리스(schemaless)에대해 먼저 공부해 보겠습니다.
맨처음 접했을때는 RDB 처럼 테이블이 없다면 데이터를 insert하였을때 데이터가 안들어가는줄 알았습니다.

하지만 ElasticSearch에서는 스키마리스라는 기능을 제공합니다. 바로 인덱스가 없이도 데이터를 색인한다면 데이터 추가와 동시에 인덱스가 생성이 되는 기능을 제공합니다. Json형식의 Key Value값을 분석하여 자동으로 필드명과 속성 정보를 자동으로 생성해 줍니다.

ElasticSearch를 Kibana 에 연결하여 Kibana의 Devtool에 다음과 같이 입력해보도록 합니다.
현재 movie라는 인덱스는 존재하지 않습니다

PUT /movie/_doc/1
{
  "movieCd" : "1",
  "movieNm" : "반지의 제왕3 왕의 귀환",
  "movieNmEn": "The Lord Of The Rings: The Return Of The King",
  "prdtYear" : "2003",
  "repNationNm" : "뉴질랜드",
  "regGenreNm" : "판타지" 
}

실행을 해보면 나의 생각과 다르게 실행되어 다음과 같은 결과를 얻을 수 있었습니다.

{
  "_index" : "movie",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

총 2개의 샤드로 구성되어있으며 _id가 1인 도큐먼트가 성공적으로 입력되었다는 내용입니다. 스키마리스 기능을 통해 자동으로 JSON 키 벨류를 분석해 필드명과 속성정보가 자동으로 매칭되었다는 것입니다. 그렇다면 생성된 _mapping정보를 확인해보겠습니다

GET /movie/_mapping
{}

를 실행시켜 매핑된 정보를 보면 다음과 같습니다.

{
  "movie" : {
    "mappings" : {
      "properties" : {
        "movieCd" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "movieNm" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "movieNmEn" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
               
        "prdtYear" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "regGenreNm" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "repNationNm" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

기본적으로 모든 필드가 type이 text이며 keyword 타입을 동시에 제공하는 멀티 필드로 구성되어있습니다.
스키마리스로 생성된 경우 text타입만 필요할수도 있고 keyword만 필요한 상황에서 불필요한 데이터 공간의 낭비가 됩니다. 비록 편리하긴하지만 특수한 상황에서만 사용하는것을 권장합니다.
(저는 실제로 사용하지 않습니다.)

따라서 실무에서는 스키마리스를 많이 사용하지 않고 인덱스를 만들어놓고 도큐먼트를 색인합니다.


💡 인덱스 생성

스키마리스를 봤으니 실제로 인덱스를 생성해보도록 하겠습니다.
인덱스를 실제로 등록할때는 매핑이라는 세부 설정을 이용하여 생성할 수 있다.

매핑을 설정한다는것은 도큐먼트에 포함된 필드, 필드 타입등을 세세하게설정이 가능합니다.

단, 한번 생성된 매핑정보는 변경이 불가능하여 잘못생성하거나 변경하여야 한다면 다시만든후 데이터들을 다시 색인해합니다.

위에 스키마리스로 생성한 movie 인덱스를 매핑정보를 직접 추가하여 생성해보겠습니다.

PUT /movie 
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 0
  },
  
  "mappings": {
      "properties" : {
        "movieCd" : {"type" : "integer"},
        "movieNm" : {"type":"text"},
        "movieNmEn": {"type":"text"},
        "prdtYear" : {"type":"integer"},
        "repNationNm" : {"type" : "keyword"},
        "regGenreNm" : {"type" : "keyword"}
      }
  }
}

// index mapping 정보 조회
GET /movie/_mapping
{}

{
  "movie" : {
    "mappings" : {
      "properties" : {
        "movieCd" : {
          "type" : "integer"
        },
        "movieNm" : {
          "type" : "text"
        },
        "movieNmEn" : {
          "type" : "text"
        },
        "prdtYear" : {
          "type" : "integer"
        },
        "regGenreNm" : {
          "type" : "keyword"
        },
        "repNationNm" : {
          "type" : "keyword"
        }
      }
    }
  }
}

스키마리스로 생성된 내용과 비슷해보면 field타입이 없습니다.

단순히 문자열만 저장하고싶다면 keyword를 형태소 분석을 위한 경우 text 타입을사용하면 됩니다.


💡 인덱스 삭제

생성을 했다면 당연히 삭제하는 것도 있어야 할것이다 앞에있던 포스팅에서 봤지만 삭제를 하기위해서는 DELETE 메소드를 사용하여 삭제합니다.

위에 생성한 인덱스를 삭제하려면 다음과 같이 하면 됩니다.

DELETE /movie

정말 간단합니다. 단 , 간단한 만큼 한번 삭제되면 다시 복구할 수 없으니 신중하게 메소드를 삭제하길 바랍니다.


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

0개의 댓글