본문 바로가기

시스템/DB

ElasticSearch (Mapping & Analysis)

분석 API 소개

  • 때로는 텍스트 분석이라고도 함
    • 텍스트 필드/값에 적용 가능
    • 문서 인덱스 시 텍스트 값이 분석됨
    • 결과는 검색 등에 효율적인 데이터 구조에 저장
    • _source 객체는 문서 검색 시 사용되지 않음
      • 문서 색인 시 지정된 정확한 값을 포함함

문자 필터

  • 문자를, 추가, 제거 또는 변경함
    • 분석기는 0개 이상의 문자 필터를 포함함
    • 문자 필터는 지정된 순서대로 적용됨
    • 예시 (html_strip 필터)
      • 입력: "I'm in a <em>good</em> mood - and I <strong>love</strong> açaí!"
      • 출력: "I'm in a good mood - and I love açaí!"

토큰나이저

  • 분석기는 하나의 토큰화기를 포함함
    • 문자열을 토큰화함, 즉 토큰으로 분할함
    • 토큰화 과정에서 문자가 제거될 수 있음
    • 예시
      • 입력: "I REALLY like beer!"
      • 출력: ["I", "REALLY", "like", "beer"]

토큰 필터

  • 토큰화기의 출력(즉, 토큰)을 입력으로 받음
    • 토큰 필터는 토큰을 추가, 제거 또는 수정할 수 있음
    • 분석기는 0개 이상의 토큰 필터를 포함함
    • 토큰 필터는 지정된 순서대로 적용됨
    • 예시 (소문자 필터)
      • 입력: ["I", "REALLY", "like", "beer"]
      • 출력: ["i", "really", "like", "beer"]

내장 및 사용자 정의 구성 요소

  • 내장된 분석기, 문자 필터, 토큰화기 및 토큰 필터를 사용할 수 있음
    • 사용자 정의 구성 요소도 구축 가능함
      • 이 섹션의 뒷부분에서 방법을 볼 수 있음

 

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

는 아래와 동일하다

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


>>>

더보기

{
  "tokens" : [
    {
      "token" : "2",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "",
      "position" : 0
    },
    {
      "token" : "guys",
      "start_offset" : 2,
      "end_offset" : 6,
      "type" : "",
      "position" : 1
    },
    {
      "token" : "walk",
      "start_offset" : 7,
      "end_offset" : 11,
      "type" : "",
      "position" : 2
    },
    {
      "token" : "into",
      "start_offset" : 12,
      "end_offset" : 16,
      "type" : "",
      "position" : 3
    },
    {
      "token" : "a",
      "start_offset" : 19,
      "end_offset" : 20,
      "type" : "",
      "position" : 4
    },
    {
      "token" : "bar",
      "start_offset" : 21,
      "end_offset" : 24,
      "type" : "",
      "position" : 5
    },
    {
      "token" : "but",
      "start_offset" : 26,
      "end_offset" : 29,
      "type" : "",
      "position" : 6
    },
    {
      "token" : "the",
      "start_offset" : 30,
      "end_offset" : 33,
      "type" : "",
      "position" : 7
    },
    {
      "token" : "third",
      "start_offset" : 34,
      "end_offset" : 39,
      "type" : "",
      "position" : 8
    },
    {
      "token" : "ducks",
      "start_offset" : 43,
      "end_offset" : 48,
      "type" : "",
      "position" : 9
    }
  ]
}

 

 

역 색인(Inverted Indices) 이해

소개

  • 필드의 값은 여러 데이터 구조 중 하나에 저장됨
    • 데이터 구조는 필드의 데이터 타입에 따라 다름
    • 효율적인 데이터 접근(예: 검색)을 보장함
    • Elasticsearch가 아닌 Apache Lucene에 의해 처리됨
    • 이 강의는 역색인에 초점을 맞춤

역색인

  • 용어와 해당 용어를 포함하는 문서 간의 매핑
    • 분석기 컨텍스트 외부에서는 "용어(terms)"라는 용어를 사용함
    • 용어는 알파벳 순으로 정렬됨
    • 역색인은 용어와 문서 ID 외에도 더 많은 정보를 포함함
      • 예: 관련성 점수 매기기 위한 정보
    • 텍스트 필드당 하나의 역색인
    • 다른 데이터 타입은 예를 들어 BKD 트리를 사용함

요약 (1/2)

  • 텍스트 필드의 값은 분석되고 결과는 역색인 내에 저장됨
    • 각 필드는 전용 역색인을 가짐
    • 역색인은 용어와 해당 용어를 포함하는 문서 간의 매핑임
    • 성능상의 이유로 용어는 알파벳 순으로 정렬됨
    • Elasticsearch가 아닌 Apache Lucene에 의해 생성되고 유지됨

요약 (2/2)

  • 역색인은 빠른 검색을 가능하게 함
    • 역색인은 다른 데이터도 포함함
      • 예: 관련성 점수 매기기에 사용되는 것들(나중에 다룸)
    • Elasticsearch(기술적으로는 Apache Lucene)는 다른 데이터 구조도 사용함
      • 예: 숫자 값, 날짜 및 지리 공간 데이터를 위한 BKD 트리

역 색인 이미지화

 

Mapping

매핑이란 무엇인가?

  • 문서의 구조(예: 필드 및 데이터 타입)를 정의함
    • 값이 어떻게 색인되는지 구성하는 데도 사용됨
  • 관계형 데이터베이스의 테이블 스키마와 유사함
  • 명시적 매핑
    • 필드 매핑을 직접 정의함
  • 동적 매핑
    • Elasticsearch는 동적 매핑을 지원하기 때문에, 인덱스에 도큐먼트를 추가하면 자동 매핑 생성된다.
PUT books/_doc/1
{
  "title": "Romeo and Juliet",
  "author": "William Shakespeare",
  "category": "Tragedies",
  "publish_date": "1562-12-01T00:00:00",
  "pages": 125
}
GET books/_mapping
>>>
{
  "books" : {
    "mappings" : {
      "properties" : {
        "author" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "category" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "pages" : {
          "type" : "long"
        },
        "publish_date" : {
          "type" : "date"
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}


참고: https://esbook.kimjmin.net/07-settings-and-mappings/7.2-mappings

 

데이터 타입

object 데이터 타입

  • 모든 JSON 객체에 사용됨
    • 객체는 중첩될 수 있음
    • properties 매개변수를 사용하여 매핑됨
    • 객체는 Apache Lucene에서 객체로 저장되지 않음
      • 객체는 유효한 JSON을 색인할 수 있도록 변환됨
      • 특히, 객체는 평면화됨(flattened)

nested 데이터 타입

  • object 데이터 타입과 유사하지만, 객체 관계를 유지함
    • 객체 배열을 색인할 때 유용함
  • 객체를 독립적으로 쿼리할 수 있게 함
    • nested 쿼리를 사용해야 함
  • nested 객체는 숨겨진 문서로 저장됨

keyword 데이터 타입

  • 값의 정확한 일치에 사용됨
    • 일반적으로 필터링, 집계 및 정렬에 사용됨
    • 예: PUBLISHED 상태의 기사 검색
  • 전체 텍스트 검색의 경우 대신 text 데이터 타입을 사용함
    • 예: 기사의 본문 텍스트 검색

 

keyword 필드가 분석되는 방법

keyword 필드는 keyword 분석기로 분석됨

  • keyword 분석기는 아무 작업도 하지 않는(no-op) 분석기임
    • 수정되지 않은 문자열을 단일 토큰으로 출력함
    • 이 토큰은 역색인에 배치됨
  • keyword 필드는 정확한 일치, 집계 및 정렬에 사용됨

 

타입 강제(Coercion)

타입 강제 변환 소개

  • 문서 색인 시 데이터 타입이 검사됨
    • 유효성이 검증되며, 일부 유효하지 않은 값은 거부됨
    • 예: text 필드에 객체를 색인하려고 시도함
  • 때로는 잘못된 데이터 타입을 제공해도 괜찮음

_source 객체 이해하기

  • 색인 시 제공된 값("7.4")을 포함함
    • 색인된 값(7.4)이 아님
  • 검색 쿼리는 _source가 아닌 색인된 값을 사용함
    • BKD 트리, 역색인 등
  • _source는 값이 어떻게 색인되는지 반영하지 않음
    • _source의 값을 사용할 경우 강제 변환을 염두에 둘 것
    • 이 예시에서는 문자열 또는 부동 소수점일 수 있음

몇 가지 더 알아둘 점...

  • 정수 필드에 부동 소수점을 제공하면 정수로 잘림
  • 동적 매핑에는 강제 변환이 사용되지 않음
    • 새 필드에 "7.4"를 제공하면 text 매핑이 생성됨
  • 항상 올바른 데이터 타입을 사용하도록 노력할 것
    • 특히 필드를 처음 색인할 때
  • 강제 변환 비활성화는 선호도 문제임
    • 기본적으로 활성화되어 있음

 

배열 이해

배열 소개

  • 배열 데이터 타입이라는 것은 존재하지 않음
    • 모든 필드는 0개 이상의 값을 포함할 수 있음
      • 구성이나 매핑이 필요하지 않음
      • 문서 색인 시 배열을 제공하기만 하면 됨
    • products 색인의 tags 필드에 이것을 적용했음

제약 조건

  • 배열 값은 동일한 데이터 타입이어야 함
    • 강제 변환은 이미 매핑된 필드에만 작동함
      • 동적 매핑으로 필드 매핑을 생성하는 경우, 배열은 동일한 데이터 타입을 포함해야 함
    • 강제 변환 사용을 권장하지 않음(적어도 의도적으로는)

중첩 배열

  • 배열은 중첩 배열을 포함할 수 있음
    • 배열은 색인 중에 평면화됨
    • [ 1, [ 2, 3 ] ]는 [ 1, 2, 3 ]이 됨

작은 알림 객체 배열을 독립적으로 쿼리해야 하는 경우 nested 데이터 타입을 사용하는 것을 잊지 마세요.

 

POST /_analyze
{
  "text": ["Strings are simply", "merged together."],
  "analyzer": "standard"
}

 

매핑 정의

PUT /reviews
{
  "mappings": {
    "properties": {
      "rating" : {"type": "float"},
      "content": {"type": "text"},
      "product_id": {"type": "integer"},
      "author": {
        "properties": {
          "first_name":{"type": "text"},
          "last_name": {"type": "text"},
          "email": {"type": "keyword"}
        }
      }
    }
  }
}

 

PUT /reviews/_doc/1
{
  "rating": 5.0,
  "content": "Outstanding course! Bo really taught me a lot about Elasticsearch!",
  "product_id": 123,
    "author": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "johndoe123@example.com"
  }
}

 

GET /reviews/_mapping


{
  "reviews" : {
    "mappings" : {
      "properties" : {
        "author" : {
          "properties" : {
            "email" : {
              "type" : "keyword"
            },
            "first_name" : {
              "type" : "text"
            },
            "last_name" : {
              "type" : "text"
            }
          }
        },
        "content" : {
          "type" : "text"
        },
        "product_id" : {
          "type" : "integer"
        },
        "rating" : {
          "type" : "float"
        }
      }
    }
  }
}
GET /reviews/_mapping/field/content

field를 붙여야 한다(?)
{
  "reviews" : {
    "mappings" : {
      "content" : {
        "full_name" : "content",
        "mapping" : {
          "content" : {
            "type" : "text"
          }
        }
      }
    }
  }
}
GET /reviews/_mapping/field/author.email {
  "reviews" : {
    "mappings" : {
      "author.email" : {
        "full_name" : "author.email",
        "mapping" : {
          "email" : {
            "type" : "keyword"
          }
        }
      }
    }
  }
}

 

혹은 

(⭐️) Dot notation 사용

계층 필드를 표현할 때는 아래와 같이 하는 것이 편하다.

 

PUT /reviews_dot_notation
{
  "mappings": {
    "properties": {
      "rating" : {"type": "float"},
      "content": {"type": "text"},
      "product_id": {"type": "integer"},
      "author.first_name":{"type": "text"},
      "author.last_name": {"type": "text"},
      "author.email": {"type": "keyword"}
    }
  }
}

GET /reviews_dot_notation/_mapping

GET /reviews/_mapping

와 결과 동일하다.

 

존재하는 인덱스에 매핑 추가

PUT /reviews/_mapping
{
  "properties": {
    "created_at": {
      "type": "date"
    }
  }
}

 

날짜 필드 소개

날짜 필드 소개

  • 다음 세 가지 방법 중 하나로 지정됨:
    • 특별히 형식화된 문자열
    • 에포크 이후 밀리초(long)
    • 에포크 이후 초(integer)
  • 에포크는 1970년 1월 1일을 의미함
  • 사용자 정의 형식도 지원됨

날짜 필드의 기본 동작

  • 지원되는 세 가지 형식:
    • 시간이 없는 날짜
    • 시간이 있는 날짜
    • 에포크 이후 밀리초(long)
  • 시간대가 지정되지 않은 경우 UTC 시간대로 가정함
  • 날짜는 ISO 8601 명세에 따라 형식화되어야 함

날짜 필드가 저장되는 방법

  • 내부적으로 에포크 이후 밀리초(long)로 저장됨
  • 색인 시 제공하는 모든 유효한 값은 내부적으로 long 값으로 변환됨
  • 날짜는 UTC 시간대로 변환됨
  • 검색 쿼리에도 동일한 날짜 변환이 발생함

요약

  • 날짜는 다음 세 가지 방법 중 하나로 지정됨:
    • 특별히 형식화된 문자열(기본값은 ISO 8601 - 사용자 정의 형식 사용 가능)
    • 에포크 이후 밀리초
    • 에포크 이후 초
  • 날짜는 내부적으로 long 값으로 저장됨(먼저 UTC로 변환됨)
    • 검색 쿼리에도 동일한 변환이 이루어짐
  • 기본 날짜 필드에 UNIX 타임스탬프를 제공하지 말 것

요약

이 내용은 Elasticsearch에서 날짜 필드의 처리 방식에 대해 설명합니다. 날짜는 형식화된 문자열, 에포크 이후 밀리초, 또는 에포크 이후 초로 지정할 수 있습니다. 내부적으로는 모든 날짜가 UTC 시간대로 변환되어 long 값(밀리초)으로 저장됩니다. 검색 쿼리 시에도 동일한 변환 과정이 발생하며, 기본 날짜 필드에는 UNIX 타임스탬프 형식을 사용하지 않는 것이 좋습니다.

 

매핑 파라미터

- 참고: https://esbook.kimjmin.net/07-settings-and-mappings/7.2-mappings/7.2.3-date

 

소개

  • 가장 중요한 매핑 매개변수를 다룰 것임
    • 그러나 이것은 완전한 목록은 아님
      • 다른 대부분의 매개변수는 매우 전문적이거나 거의 사용되지 않음

format 매개변수

  • 날짜 필드의 형식을 사용자 정의하는 데 사용됨
    • 가능한 기본 형식 사용을 권장함
      • "strict_date_optional_time||epoch_millis"
    • Java의 DateFormatter 구문 사용
      • 예: "dd/MM/yyyy"
    • 내장 형식 사용
      • 예: "epoch_second"

format 매개변수 (예시)

PUT /sales
{
  "mappings": {
    "properties": {
      "purchased_at": {
        "type": "date",
        "format": "dd/MM/yyyy"
      }
    }
  }
}

PUT /sales
{
  "mappings": {
    "properties": {
      "purchased_at": {
        "type": "date",
        "format": "epoch_second"
      }
    }
  }
}

properties 매개변수

  • 객체 및 중첩 필드의 중첩 필드를 정의함
PUT /sales
{
  "mappings": {
    "properties": {
      "sold_by": {
        "properties": {
          "name": { "type": "text" }
        }
      }
    }
  }
}

PUT /sales
{
  "mappings": {
    "properties": {
      "products": {
        "type": "nested",
        "properties": {
          "name": { "type": "text" }
        }
      }
    }
  }
}

coerce 매개변수

  • 값의 강제 변환을 활성화하거나 비활성화하는 데 사용됨(기본적으로 활성화됨)
PUT /sales
{
  "settings": {
    "index.mapping.coerce": false
  },
  "mappings": {
    "properties": {
      "amount": {
        "type": "float",
        "coerce": true
      }
    }
  }
}

PUT /sales
{
  "mappings": {
    "properties": {
      "amount": {
        "type": "float",
        "coerce": false
      }
    }
  }
}

doc_values 소개

  • Elasticsearch는 여러 데이터 구조를 사용함
    • 단일 데이터 구조가 모든 목적을 충족하지는 않음
  • 역색인은 텍스트 검색에 탁월함
    • 다른 많은 데이터 접근 패턴에는 잘 작동하지 않음
  • "Doc values"는 Apache Lucene에서 사용하는 또 다른 데이터 구조임
    • 다른 데이터 접근 패턴(문서 → 용어)에 최적화됨

doc_values 소개

  • 본질적으로 "역전되지 않은" 역색인임
    • 정렬, 집계 및 스크립팅에 사용됨
    • 대체가 아닌 추가 데이터 구조임
    • Elasticsearch는 자동으로 적절한 데이터 구조를 쿼리함

doc_values 비활성화

  • 디스크 공간을 절약하기 위해 doc_values 매개변수를 false로 설정함
    • 또한 색인 처리량을 약간 증가시킴
  • 집계, 정렬 또는 스크립팅을 사용하지 않을 경우에만 doc values를 비활성화함
  • 특히 대규모 색인에 유용함; 일반적으로 소규모 색인에는 가치가 없음
  • 문서를 새 색인으로 다시 색인하지 않고는 변경할 수 없음
    • 주의해서 사용하고, 필드가 어떻게 쿼리될지 예상해 볼 것

doc_values 매개변수 (예시)

PUT /sales
{
  "mappings": {
    "properties": {
      "buyer_email": {
        "type": "keyword",
        "doc_values": false
      }
    }
  }
}

norms 매개변수

  • 관련성 점수 계산에 사용되는 정규화 요소
    • 결과를 필터링할 뿐만 아니라 순위를 매기길 원하는 경우가 많음
    • 디스크 공간을 절약하기 위해 norms를 비활성화할 수 있음
      • 관련성 점수 계산에 사용되지 않을 필드에 유용함
      • 필드는 여전히 필터링 및 집계에 사용할 수 있음

norms 매개변수 (예시)

PUT /products
{
  "mappings": {
    "properties": {
      "tags": {
        "type": "text",
        "norms": false
      }
    }
  }
}

index 매개변수

  • 필드에 대한 색인을 비활성화함
    • 값은 여전히 _source 내에 저장됨
    • 필드를 검색 쿼리에 사용하지 않을 경우 유용함
    • 디스크 공간을 절약하고 색인 처리량을 약간 향상시킴
    • 종종 시계열 데이터에 사용됨
    • 색인이 비활성화된 필드도 여전히 집계에 사용할 수 있음

index 매개변수 (예시)

PUT /server-metrics
{
  "mappings": {
    "properties": {
      "server_id": {
        "type": "integer",
        "index": false
      }
    }
  }
}

null_value 매개변수

  • NULL 값은 색인되거나 검색될 수 없음
    • NULL 값을 다른 값으로 대체하기 위해 이 매개변수를 사용함
    • 명시적 NULL 값에만 작동함
    • 대체 값은 필드와 동일한 데이터 타입이어야 함
    • _source 내에 저장된 값에는 영향을 미치지 않음

null_value 매개변수 (예시)

PUT /sales
{
  "mappings": {
    "properties": {
      "partner_id": {
        "type": "keyword",
        "null_value": "NULL"
      }
    }
  }
}

copy_to 매개변수

  • 여러 필드 값을 "그룹 필드"에 복사하는 데 사용됨
    • 대상 필드의 이름을 값으로 지정하기만 하면 됨
    • 예: first_name 및 last_name → full_name
    • 용어/토큰이 아닌 값이 복사됨
      • 대상 필드의 분석기가 값에 사용됨
    • 대상 필드는 _source의 일부가 아님

copy_to 매개변수 (예시)

PUT /sales
{
  "mappings": {
    "properties": {
      "first_name": {
        "type": "text",
        "copy_to": "full_name"
      },
      "last_name": {
        "type": "text",
        "copy_to": "full_name"
      },
      "full_name": {
        "type": "text"
      }
    }
  }
}

POST /sales/_doc
{
  "first_name": "John",
  "last_name": "Doe"
}

요약

이 문서는 Elasticsearch의 중요한 매핑 매개변수들을 설명합니다. 다양한 매개변수와 그 용도를 다루고 있으며:

  1. format 매개변수: 날짜 필드의 사용자 정의 형식 지정
  2. properties 매개변수: 객체 및 중첩 필드 구조 정의
  3. coerce 매개변수: 값의 자동 타입 변환 제어
  4. doc_values: 정렬, 집계, 스크립팅을 위한 데이터 구조
  5. norms 매개변수: 관련성 점수 계산에 사용되는 정규화 요소
  6. index 매개변수: 필드 색인 비활성화 옵션
  7. null_value 매개변수: NULL 값을 다른 값으로 대체
  8. copy_to 매개변수: 여러 필드 값을 단일 필드로 복사

이러한 매개변수들은 Elasticsearch에서 색인과 검색 성능 최적화, 디스크 공간 절약, 그리고 특정 쿼리 패턴에 맞는 데이터 구조 구성에 중요합니다.

 

존재하는 매핑을 업데이트

PUT /reviews/_mapping
{
  "properties": {
    "author": {
      "properties": {
        "email": {
          "type": "keyword",
          "ignore_above": 256
        }
      }
    }
  }
}
{
  "reviews" : {
    "mappings" : {
      "properties" : {
        "author" : {
          "properties" : {
            "email" : {
              "type" : "keyword",
              "ignore_above" : 256
            },
            "first_name" : {
              "type" : "text"
            },
            "last_name" : {
              "type" : "text"
            }
          }
        },
        "content" : {
          "type" : "text"
        },
        "create_at" : {
          "type" : "date"
        },
        "product_id" : {
          "type" : "integer"
        },
        "rating" : {
          "type" : "float"
        }
      }
    }
  }
}

 

Reindex API 사용 Reindexing

_source 데이터 유형

  • 데이터 유형은 값이 어떻게 색인되는지를 반영하지 않음
  • _source는 색인 시 제공된 필드 값을 포함함
  • 검색 결과에서 _source 값을 활용하는 것이 일반적임
    • 예를 들어, 키워드 필드에서 문자열을 기대할 수 있음
  • 재색인(Reindexing) 시 _source 값을 수정할 수 있음
  • 또는 애플리케이션 수준에서 처리할 수도 있음

필드 제거

  • 필드 매핑(Field mappings)은 삭제할 수 없음
  • 문서를 색인할 때 특정 필드를 생략할 수 있음
  • 디스크 공간을 회수할 필요가 있을 수도 있음
    • 이미 색인된 값은 여전히 디스크 공간을 차지함
    • 대규모 데이터 세트의 경우 공간 절약이 가치 있을 수 있음
      • 더 이상 해당 값이 필요하지 않다고 가정할 때

스크립트 내 ctx.op 사용

  • 일반적으로 쿼리 파라미터를 사용하는 것이 가능함
  • 보다 고급 사용 사례에서는 ctx.op를 활용할 수 있음
  • 성능 측면에서는 쿼리 파라미터를 사용하는 것이 더 효율적이며 선호됨
  • "delete"를 지정하면 대상 인덱스에서 문서가 삭제됨
    • 대상 인덱스가 비어 있지 않을 수도 있음
    • 종종 Delete by Query API를 사용하여 동일한 작업을 수행할 수 있음

Reindex API의 파라미터

  • 우리가 다룬 것보다 더 많은 파라미터가 존재함
    • 예: 버전 충돌(version conflicts) 처리
  • 문서를 재색인하기 전에 스냅샷이 생성됨
  • 기본적으로 버전 충돌이 발생하면 쿼리가 중단됨
  • 대상 인덱스가 반드시 비어 있을 필요는 없음

배치 처리 및 제한(Throttling)

  • Reindex API는 배치 단위로 작업을 수행함
    • Update by Query 및 Delete by Query API와 유사함
    • 내부적으로 Scroll API를 사용함
    • 이 방식 덕분에 수백만 개의 문서를 효율적으로 재색인할 수 있음
  • 성능 영향을 제한하기 위해 Throttling을 설정할 수 있음
    • 운영(Production) 클러스터에서 유용함
  • 대량 문서를 재색인해야 한다면 공식 문서를 참고하는 것이 좋음

POST /_reindex
{
  "source": {
    "index": "reviews"
  },
  "dest": {
    "index": "reviews_new"
  }
}

 

특정 문서만 리인덱스

source 필터링

필드 이름 변경

 

https://github.com/codingexplained/complete-guide-to-elasticsearch/blob/master/Mapping%20%26%20Analysis/reindexing-documents-with-the-reindex-api.md

 

complete-guide-to-elasticsearch/Mapping & Analysis/reindexing-documents-with-the-reindex-api.md at master · codingexplained/com

Contains all of the queries used within the Complete Guide to Elasticsearch course. - codingexplained/complete-guide-to-elasticsearch

github.com

 

Alias 설정

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "reviews",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "rating" : 5.0,
          "content" : "Outstanding course! Bo really taught me a lot about Elasticsearch!",
          "product_id" : 123,
          "author" : {
            "first_name" : "John",
            "last_name" : "Doe",
            "email" : "johndoe123@example.com"
          }
        }
      }
    ]
  }
}
GET /reviews/_search
{
  "query": {
    "match": {
      "content": "outstanding"
    }
  }
}


Alias를 설정하면
PUT /reviews/_mapping
{
  "properties": {
    "comment": {
      "type": "alias",
      "path": "content"
    }
  }
}


아래처럼 해도 결과가 나온다.

GET /reviews/_search
{
  "query": {
    "match": {
      "comment": "outstanding"
    }
  }
}


 

멀티 필드 매핑

PUT /multi_field_test
{
  "mappings": {
    "properties": {
      "description": {
        "type": "text"
      },
      "ingredients": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

 

텍스트 매핑과 키워드 매핑 모두가 가능하다.

Querying the text mapping Querying the keyword mapping
GET /multi_field_test/_search
{
  "query": {
    "match": {
      "ingredients": "Spaghetti"
    }
  }
}
GET /multi_field_test/_search
{
  "query": {
    "term": {
      "ingredients.keyword": "Spaghetti"
    }
  }
}

 

(⭐️) 인덱스 템플릿 

인덱스 템플릿은 유사한 패턴의 인덱싱된 데이터를 채반 할 때 유용하다

POST /access-logs-2023-01/_docs 명령시

 

인덱스가 존재하나?

--> 존재한다면 존재하는 인덱스로 인덱싱한다.

--> 존재하지 않는다면,

 

인덱스 이름과 인덱스 템플릿이 매칭되나?

--> 매칭되지 않는다면 인덱스 생성

--> 매칭된다면 인덱스 템플릿을 기준으로 인덱스 생성

새로운 인덱스로 문서 인덱싱

 

 

인덱스 템플릿이 오버랩 된다면 priority로 구분할 수 있다.

 

 

 

Dynamic Mapping

- 동적으로 타입을 파악하여 매핑을 만든다.

 

Explicit & Dynamic Mapping 결합

PUT /people
{
  "mappings": {
    "properties": {
      "first_name": {
        "type": "text"
      }
    }
  }
}

POST /people/_doc
{
  "first_name": "Bo",
  "last_name" : "Donghoon" # 해당 매핑은 없지만, 자동 필드 매핑을 생성한다. 
}

GET /people/_mapping
{
  "people" : {
    "mappings" : {
      "properties" : {
        "first_name" : {
          "type" : "text"
        },
        "last_name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

 

 

Configure Dynamic Mapping

PUT /people
{
  "mappings": {
    "dynamic": false,
    "properties": {
      "first_name": {
        "type": "text"
      }
    }
  }
}


POST /people/_doc
{
  "first_name": "Bo",
  "last_name" : "Donghoon"
}

GET /people/_mapping

GET /people/_search
{
  "query": {
    "match": {
      "first_name": "Bo"
    }
  }
}
{
  "people" : {
    "mappings" : {
      "dynamic" : "false",
      "properties" : {
        "first_name" : {
          "type" : "text"
        }
      }
    }
  }
}
>>>
last_name의 매핑이 생성되지 않는다.

>>> 
"first_name"으로 검색하면 검색되지만,
"last_name"으로 검색하면 검색되지 않는다.
inverted index가 생성되지 않기 때문.
PUT /people
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "first_name": {
        "type": "text"
      }
    }
  }
}

POST /people/_doc # 해당 명령을 허락하지 않는다.
{
  "first_name": "Bo",
  "last_name" : "Donghoon"
}
 

 

요약:

  • dynamic: false 설정 시:
    • 새로운 필드는 무시되고 인덱싱되지 않지만 _source에는 저장됨.
    • 예: last_name 필드는 인덱스가 없어 검색 불가.
    • 명시적 매핑 없이는 필드 인덱싱 불가.
    • 동적 매핑이 활성화되면 자동으로 매핑 생성 가능.
  • 더 나은 방법: dynamic: "strict" 설정
    • 매핑되지 않은 필드는 Elasticsearch가 거부함.
    • 모든 필드를 명시적으로 매핑해야 함.
    • 관계형 데이터베이스처럼 동작함.

동적 매핑 상속

  • 루트에 dynamic: "strict" 설정하고, 특정 필드(specifications.other)에만 dynamic: true로 오버라이드 가능
PUT /computers
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "name": {
        "type": "text"
      },
      "specifications": {
        "properties": {
          "cpu": {
            "properties": {
              "name": {
                "type": "text"
              }
            }
          },
          "other": {
            "dynamic": true,
            "properties": { ... }
          }
        }
      }
    }
  }
}

 

숫자 탐지 (numeric_detection)

  • 문자열이 숫자 형태이면 자동으로 float 또는 long 타입으로 매핑
PUT /computers
{
  "mappings": {
    "numeric_detection": true
  }
}
(예시)
POST /computers/_doc
{
  "specifications": {
    "other": {
      "max_ram_gb": "32", # long
      "bluetooth": "5.2" # float
    }
  }
}

날짜 탐지

  • date_detection: false → 자동 날짜 감지 비활성화
  • dynamic_date_formats → 사용자 정의 날짜 형식 설정 가능
PUT /computers
{
  "mappings": {
    "date_detection": false
  }
}
PUT /computers
{
  "mappings": {
    "dynamic_date_formats": ["dd-MM-yyyy"]
  }
}

 


출처: https://www.udemy.com/course/elasticsearch-complete-guide/

반응형

'시스템 > DB' 카테고리의 다른 글

ElasticSearch (Mapping Documents)  (0) 2025.03.07
SELECT 기본 용법  (0) 2022.08.02