본문 바로가기
TIL/엘라스틱 서치

Elastic Search : Complete Guide to ElasticSearch - Mapping & Analysis

by yeon_zoo 2024. 1. 17.

[analysis]

  • text analysis 라는 말로도 불림
  • text 필드에 대해서만 가능
  • 도큐먼트를 저장하기 전에 먼저 텍스트 값들이 분석된다.
  • 검색할 때 편한 구조로 저장하기 위해서이다.
  • 우리가 쿼리할 때 _source 를 기준으로 검색한다고 해도 탐색을 진행할 때 이걸 사용하진 않는다.

 

analyzer의 3요소

  • Character filters
    • 문자를 추가/제거. 변경한다
    • Analyzer은 0개 이상의 캐릭터 필터를 가진다.
    • 정의된 순서대로 적용된다.
    • ex) html_strip
  • Tokenizer
    • analyzer은 하나의 tokenizer를 갖는다
    • 텍스트를 토큰화 한다. (이 때 문자는 제거될 수 있다)
    • 텍스트를 단어 단위로 자르게 된다.
    • 원본 문자열의 각 토큰에 대한 문자 offset을 별도로 저장한다.
  • Token filters
    • 입력값으로 토크나이저의 출력값을 받는다
    • 토큰 필터는 토큰을 추가, 삭제, 수정할 수 있다
    • analyzer는 0개 이상의 토큰 필터를 가진다
    • 정의된 순서대로 적용된다
    • ex) lowercase

 

POST /_analyze // 기성 analyzer
{
  "text": "2 guys walk into a bar  , but the third… DUCKS! :-)",
  "analyzer": "standard"
}



POST /_analyze // 커스텀 analyzer
{
  "text": "2 guys walk into a bar  , but the third… DUCKS! :-)",
  "char_filter": [],
  "tokenizer": "standard",
  "filter": ["lowercase"]
}

 

[역인덱싱]

  • 필드 값이 여러 자료 구조에 저장된다
  • 자료구조는 필드의 자료형에 따라 달라진다
  • 효율적인 데이터 접근 (검탐색 등)이 가능하게 한다
  • 아파치 루씬이 하는 것 (es 관할은 아니다..)
  • 용어와 어떤 도큐먼트가 그 용어를 포함하는지를 매핑하는 것
  • analyzer 을 논할 때를 제외하고는 토큰이라고 하지 않고 용어?(term)이라고 한다
  • 루씬에 저장되는 역인덱스는 용어와 도큐먼트 아이디 말고도 추가적인 정보(유사도 점수 관련한 정보 등)를 저장한다.
  • 각 텍스트 필드마다 역인덱스 테이블이 생성된다. (두 개의 텍스트 필드가 존재하는 인덱스 매핑이라면 역인덱스 테이블도 두 개가 생성된다)
  • 숫자, 날짜, 지리공간 데이터 형의 필드들은 BKD 트리 형태의 자료구조를 가진다.

 

[매핑]

  • 도큐먼트의 구조를 정의(데이터 타입 등) - 값이 어떻게 인덱싱됐는지도 알게 된다
  • RDB의 스키마와 동일
  • 명시적 매핑 / 다이나믹 매핑 -> 두 개가 합쳐져서 사용될 수도 있음.

 

[자료형]

  • 기본 자료형
  • ip 나 지리 데이터형 같은 것도 지원
  • Object -> Json Object 로 지원
    • properties 파라미터를 사용해서 매핑된다
    • 루씬에서 objects로 저장되는 건 아니다
    • 루씬에서 잘 저장하기 위해서 flatten 된 형태로 저장한다. ex) manufacturere.name 등
  • Array 타입
    • 루씬에서는 array 타입이 존재하면 여러개의 도큐먼트로 나눠서 저장한다. > 이 경우, 문제가 발생할 수 있다
    • 따라서 Nested 타입으로 저장

이 상황에 쿼리의 where AND 조건이 OR이 됨.

 

  • nested 타입
    • object 타입이랑 비슷하지만 object relationship을 유지한다 -> object 타입의 array를 저장할 때 유용하다
    • object들을 독립적으로 쿼리할 수 있도록 한다.
    • nested query를 사용해야 한다. -> 실제로는 각각을 하나의 도큐먼트로 만들어 저장한다.
    • ex) 10개의 리뷰가 달린 상품을 하나의 도큐먼트로 만든다 -> 실제로는 11개의 도큐먼트가 생성되는 것

  • keyword 타입
    • 정확히 맞는 값으로 사용. 필터링, 집계, 혹은 정렬에 자주 사용된다. (enum 값 등에도)
    • 전문 쿼리가 안됨.

 

[keyword 와 Text 자료형의 차이]

  • 키워드 분석기는 no-op (연산이 없는) 분석기이다. 원본 문자열 그대로 하나의 토큰으로 저장된다.
  • 상태값이나 이메일 주소 같은 값을 저장하기에 좋다
  • 분석기를 커스텀할 수도 있다. (ex. 이메일은 case-sensitive 하지 않으므로 lowercase 필터를 붙이고 싶을 수 있다)

 

[타입 변환(type coercion)]

  • 도큐먼트를 인덱싱할 때 데이터 타입을 조사하게 된다.
    • 유효하지 않는 값들은 거부당한다. (e.g. 텍스트 필드에 object 를 인덱싱하려고 한다거나..)
  • 종종 잘못된 데이터 타입을 받는 것도 허용된다.
    • 매핑은 float 형인데 “7.4" 라는 문자열 형이 들어온다면 -> 7.4는 숫자 값이기 때문에 float로 알아서 변환됨
    • float 형에 “7.4m” 같은 문자열 값이 들어오면 에러 발생
  • 알아서 강제 형변환이 되었다 하더라도 검색 결과는 인덱싱 할 때 입력했던 값으로 나온다.
    • 서치 쿼리는 인덱싱된 값(by. BKD, 역인덱싱 등)들을 사용하지만 _sources는 아니다
    • _source는 처음 도큐먼트 저장할 때 사용했던 값으로 반환된다! -> 이게 싫으면 처음부터 정확한 데이터 형을 제공하거나 강제 형 변환을 막아야 한다.

 

타입 변환 주의점

  • integer 필드에 floating point를 넣으면 정수형으로 자를 것이다
  • 다이나믹 매핑을 할 때 적용되는 건 아니다 (새로운 필드에 “7.4"를 넣으면 float 형 아니고 텍스트 형으로 생성됨)
  • 이러나 저러나 처음부터 정확한 데이터 형을 제공하려고 노력하는 게 필요하다
  • 타입 변환을 아예 금지하는 선호의 차이지만, 강연자는 비활성화를 선호한다고 한다. (나도.. 나중에 변환 엉망진창되는 것보단 아예 데이터 인입 불가가 나을 수도?)

댓글