Archive

[Elasticsearch] 엘라스틱서치 기본 개념 (Index / Document / Mapping / Template / Analyzer ) 본문

------- DE -------/ELK

[Elasticsearch] 엘라스틱서치 기본 개념 (Index / Document / Mapping / Template / Analyzer )

enent 2022. 6. 2. 16:10
반응형
1. Overview
2. Index/Document/Mapping
    2.1  Index
    2.2 Document
    2.3 Mapping
3. Index Template
    3.1 Dynamic Template
4.  Analyzer
    4.1 Anlyzer 종류
    4.2 Tokenizer 종류
    4.3 Filter 종류
    4.4 Custom Analyzer

 

1. Overview

  • 모든 기능을 RestAPI 형태로 제공 (보통 kibana console에서 활용) 
  • get _cat API를 활용해 상태정보 조회 가능 (node, shard, template 등 상태정보 조회가능)

 

 

2. Index/Document/Mapping

2.1  Index

  • Index  : document를 저장하는 논리적 구분자 (RDB의 Table)
    - 하나의 인덱스에 다수의 Document가 포함
    - 동일한 Index에 있는 Document는 동일한 Schema를 가짐 = Schema 에 따라 Index를 구분하여 저장
    - 검색 성능을 위해 Document 개수 or 용량 or 날짜/시간 등을 기준으로 Index를 분리함
  • put <indexname> / delete <indexname > 을 통해 index 생성/삭제 가능

 

2.2 Document

  • Document :  ES 에서 실제 데이터를 저장하는 단위 (RDB의 Row)
    - 여러 Field / Value로 구성
  • 저장 시 데이터 형변환 시도 
    - "10" -> 10 : 숫자 Field에 들어온 문자 -> 숫자 
    - 10.0 -> 10 : 정수 Field에 들어온 소수 -> 정수

 

Document CRUD

  • CUD를 한번에 할 수 있는 Bulk API도 제공
  • Create
    - Docuemt를 생성하기 위해선 우선 Index를 먼저 생성 후 Indexing해야함
      *Indexing : Document를 Index에 포함시키는 것
PUT index1/_doc/1
{
    "name":"Jenny",
    "age":25
}

 

  • Read
    - DSL(Domain Specific Language)를 사용하여 Index내 모든 Document 가져옴
GET index1/_search

 

  • Update
    - 비용이 많이 들기 때문에 권장하지 않음 (로그 수집 용도로 사용시 수정할 일이 거의 없음)
    - 방법
      ▷ 같은 Document ID 로 Indexing하면 덮어쓰기가 되면서 새로운 데이터 추가 가능 : PUT Method 활용
PUT index1/_doc/1 {
    "name" : "mickey",
    "country" : "US"
}


          ▷ Update API 활용

POST index1/_update/1
{
  "doc" : {
  	"name" : "lee"
  }
}

 

  • Delete
    - 비용이 많이 들기 때문에 사용시 주의
    - 방법
       ▷  Delete API 활용
Delete index1/_doc/1

 

 

2.3 Mapping

  • 대용량 데이터를 빠르게 실시간으로 검색할 수 있도록 하는 과정 
  • JSON형태의 데이터를 Lucene이 이해할 수 있도록 바꿔주는 작업
  • RDB의 Schema와 유사
  • Mapping API를 활용하여 확인 가능

 

2.3.1 Dynamic Mapping

  • 자동으로 인덱스 매핑
  •  숫자 타입은 Long으로 인식하여 불필요한 메모리를 차지한다던지, 문자열의 경우 검색/정렬 등을 고려한 매핑이 제대로 되지 않는다던지 하는 단점이 있음

 

2.3.2 Explicit Mapping

  • 인덱스 매핑 직접 정의
    - 인덱스 생성할 때 정의하거나, mapping API를 이용하여 지정
    - properties 외에도 format, analyzer등 유용한 parameter 존재
PUT index2{
	"mappings" : {
    		"properties" : {
        		"age" : {"type" : "short"},
            		"name " : { "type" : "text"},
            		"gender" : { "type" : "keyword"}
            
        	}
        }
}
  • 저장할 데이터를 확실히 알고 있다면 Explicit Mapping 방식을 사용하는 것이 좋으나, 이미 정의된 Field를 수정/삭제하는 것이 불가능하다. (Field이름 / Data Type 변경을 위해서는 새로운 Index를 만들거나 Reindex API를 활용해야함.

자주 사용되는 DataType

  • Text
    - text : 전문 검색이 필요한 데이터 (텍스트를 분석함)
       ex ) 문장 
    - keyword : 정렬/집계에 사용되는 데이터 (분석 없이 통째로 indexing) 
        ex ) 범주형 데이터
  • date : 날짜/시간 데이터
  • 정수
    - byte : 부호 있는 8bit 데이터 ( -2^7 ~ 2^7-1)
    - short : 부호 있는 16bit 데이터 ( -2^15 ~ 2^15-1)
    - integer : 부호 있는 32bit 데이터 ( -2^31 ~ 2^31-1)
    - long : 부호 있는 64bit 데이터 (-2^63 ~ 2^63-1)
  • 실수
    - scaled_float : float -> 정수형으로 만든 데이터. 정확도는 떯어지나 집계 등에 사용하기 좋음
    - halt_float : 16bit 부동소수점 실수 데이터
    - double : 32bit 부동소수점 실수 데이터
    - float : 64bit 부동소수점 실수 데이터
  • boolean : T/F
  • ip : ipv4/ ipv6 
  • 위치
    - geo-point : 위도/경도
    - geo-shape : 지형
  • Range
    - integer_range, long_range, float_range, double_range, ip_range, date_range
  • object : object. 또다른 Json형태를 저장할 수 있음
  • Array
    - nested : 배열형 객체 저장 (객체를 따로 Indexing하여 배열 내부의 객체에 Query로 접근할 수 있음)
    - join : parent / child 관계 표현 가능

 

Text / Keyword / MultiField

 

1) text : 전문 검색이 필요한 데이터 (텍스트를 분석함)
    ex) 문장 


   ▶ 집계 / 정렬을 지원하지 않으며, 집계 / 정렬을 하더라도 Term기준으로 하여 다른 결과를 얻게됨
   ▶ analyzer에 의해 token으로 분리되고, 분리된 token들은 indexing됨 : Inverted Indexing(역인덱싱)
   ▶ Inverted index에 저장된 token을 Term(용어)이라고 함
   ▶ Term을 통해서 전체 문장을 검색할 수 있게 됨
        ▷ match 쿼리를 통해 Inverted Indexing 된 Term 중 일치하는 Term이 있는 document를 찾을 수 있음

GET index1/_search
{
	"query" : {
    		"match" : {
        		"contents" : "day"
        	}
   	 }
}

 

 

2) keyword : 정렬/집계에 사용되는 데이터 (분석 없이 통째로 indexing) 
     ex ) 범주형 데이터

 

     ▶ 분석기를 거치지 않고 문자열 전체가 하나의 Term으로 인덱싱
     ▶ 부분 일치 검색은 어렵지만 완전 일치 검색에는 유용

         ▷ match 쿼리를 통해 keyword를 찾을 수 있음

 

3) Multi Field : 단일 필드에 여러 하위 필드를 정의 -> 한개의 word를 text와 keyword타입으로 동시에 사용 가능 (한 개의 col이 여러타입으로 지정되는 느낌)

     ex) 문자열 데이터로 전문 검색 / 정렬 동시에 필요한 경우 사용 가능  

 

▼ message(text), contents(text/keyword) 라는 두개의 field를 가진 multifield_index 인덱스 생성. 

PUT multifield_index{
	"mappings" : {
    		"properties" : {
        		"message" : {"type" : "text"},
                	"contents" : {
                     		"type" : "text",
                    		"fields" : {
                    			"keyword" : { "type" : "keyword"}
                   	 	}
                	}
            	}
        }
   }

 

위의 예시에서 기본 타입인 text타입으로 겁색하려면 기존의 match query를 사용하면 되지만, 하위 필드인 keyword타입으로 검색하기 위해선  아래와 같은 방식을 사용해야한다.

GET multifield_index/_search
{
	"query" : {
    		"term": {
        	"contents.keyword" : "day"
        	}
   	 }
}

 

3. Index Template

  • 설정이 동일한 복수의 Index를 만들기 위해 템플릿 사용
    : Index를 Partitioning하는 경우 Index설정이 같아야 하는데 템플릿을 활용하지 않으면 관리/운영에 비효율적
    : 생성된 Template에 설정된 Index와 다른 설정의 값을 가진 Document가 들어올 경우 400 Error 발생 
  • Mapping / Setting 등의 인덱스 설정을 담고 있음
    - Mapping : properties
    - Setting : number_of_shard / number_of_replicas 등
  • Template 생성 후의 Index에만 적용됨
  • Template을 삭제하더라도 기존에 존재하던 Index에는 영향이 없음
PUT _index_template/test_template
{
    "index_patterns" : ["test_*"],
    "priority" : 1,
    "template" : {
    	"setting" : {
            "number_of_shards" : 3,
            "number_of_replicas" : 1
        },
        "mapping" : {
            "properties" : {
                "name" : {"type":"text"},
                "age" : {"type":"short"},
                "gender" : {"type" : "keyword" }
                }
            }
        }
    }

*index_patterns : 해당 패턴에 매핑되는 index에 Template 적용. 해당 예시에선 test_로 이름이 시작하는 Index들은 모두           
                               test_template에 있는 Mapping / Setting 적용

*priority : Index생성 시 매핑되는 Template이 2개 이상일때 적용될 우선순위를 설정 (숫자가 클 수록 높은 priority를 가짐)

 

 

3.1 Dynamic Template

  • Mappling을 다양하게 지정하는 Template기술
    : Mapping을 정확히 정할 수 없거나 대략적인 데이터 구조만 알고 있을 때 사용
PUT dynamic_index1
{
    "mappings":{
        "dynamic_templates":{
            {
                "my_string_fields": {
                    "match_mapping_type" : "string",
                    "mapping" : {"type" : "keyword"}
                }
            }
        }
    }
}

 

Conditions

  • match_mapping_type : datatype이 맞는지 확인 후 지정한 매핑 타입으로 변경
  • match / unmatch 
    - match : Field명이 정규식 패턴과 일치하면 해당 매핑 타입으로 변경
    - unmatch : match 패턴과 일치하는 경우 제외할 패턴을 설정할 수 있음 
  • match_pattern : match 패턴에서 사용할 수 있는 parameter조정. (ex. 정규식) 
  • path_match, path_unmatch : match/unmatch 와 유사하나, . 이 들어가는 Field명에서 사용

4.  Analyzer

  • Character Filter, Tokenizer, Token Filter 로 구성
    - Character Filter : Input 문자열을 변경하거나 불필요한 문자들 제거 = 문자열 전처리 작업
    - Tokenizer :  문자열을 Token으로 분리 (분리 시 Token 순서 / 시작 / 끝 위치 등 기록)
    - Token Filter : 분리된 Token들의 Filtering작업 (ex. 대/소문자 구분, 형태소 분석 등)
  • 하나의 Tokenizer가 반드시 포함되어야 함 ( Character Filter / Token Filter는 Optional)
  • ES에서 기본으로 제공하는 Analyzer도 있고 개발자가 직접 Filter / Tokenizer조합하여 구성 가능
  • analyze API를 사용 가능
POST _analyze
{
    "analyzer" : "stop",
    "text" : "The 10 most loving dog breads"
    }
}

 

4.1 Anlyzer 종류

  • Analyzer마다 Tokenizer와 Filter의 조합이 다르다
  • 버전에 따라 많이 바뀌기 때문에 공식문서를 확인하는 것이 좋다
    - https://www.elastic.co/guide/en/elasticsearch/reference/current/analyzer.html
  • Analyzer 
    - standard : Default. Standard Tokenizer + Lower / Stop filter
    - simple : 문자만 토큰화 ( 특수 기호 등은 토큰화 하지 않음)
    - whitespace : 공백 기준 토큰화
    - stop : Simple Analyzer + Stop filter

 

4.2 Tokenizer 종류

  • Analyzer는 하나의 Tokenizer를 반드시 포함해야 한다
  • Tokenizer
    - standard : Default. "," "." 와 같은 기호 제거하고 텍스트 기반으로 토큰화
    - lowercase:  모든 문자를 소문자로 변경해서 토큰화
    - ngram : N개의 연속된 글자 단위를 모두 토큰화함
    - uax_url_email : URL / Email 토큰화에 강점이 있음

 

4.3 Filter 종류

  • Filter사용은 Optional이며, 대부분의 Analyzer는 하나 이상의 Filter를 포함하고 있다
  • Character Filter : Tokenizer 적용 전 문자열 전처리 작업 ( ex. HTML &nbsp; -> 공백 치환 등 ) 
    - 기본 Analyzer들에는 포함되어 있지 않아서 Custom Analyzer를 만들어 사용해야 함
  • Token Filter : 토큰화된 문자들에 필터 적용 -> Token들을 삭제/추가 할 수 있음
    - lowercase/uppercase : 모든 문자를 소문자/대문자 로 변환
    - stemmer  : 문법 분석. 영어 기반 동작 (한글의 경우 한국 형태소 분석기를 사용)
    - stop : 주로 불용어 제거에 사용. 영어 기반 동작

 

 

4.4 Custom Analyzer

  • 같은 Index내에서만 유효하고, 필터 배열의 순서대로 Filter가 적용된다.
  • 가능한 소문자로 변환 후 필터를 적용하는 것을 추천한다
PUT customer_analyzer
{
    "settting" : { 
      "analysis" : { 
        "filter" : { 
          "my_stopwords" : {
            "type" : "stop",
            "stopwords" : ["lions"]
            }
          }
        },
      "analysis" : { 
        "my_analyzer" : { 
          "type" : "custom", 
          "char_filter" : [],
          "tokenizer" : "standard",
          "filter" : ["lowercase", "my_stopwords"]
          }
        }
      }
    }
}

 

 

 

 

 

 

Reference
Elastic Stack 개발부터 운영까지 - 3. ElasticSearch - Basic
반응형
Comments