시작하며

ElasticSearch는 모든 기능이 REST API 형식으로 제공된다. 학습 초반에 가장 먼저 다루게 되는 개념인 인덱스·도큐먼트 CRUD, 매핑, 벌크 API, 인덱스 템플릿, 분석기를 차례로 정리한다.

인덱스와 도큐먼트 기본 조작

CRUD - 생성(C)

ElasticSearch의 현재 상태를 빠르게 확인하는 방법으로는 cat(compact and aligned text) API를 사용하면 된다.

GET _cat

파일 구조는 index(table) > document(record) > field(column) > value 순이다. 도큐먼트를 하나의 인덱스에 포함되게 하는 작업을 **인덱싱(indexing)**이라고 한다. 아래 예시에서 index2는 인덱스 이름, _doc는 엔드포인트 구분 예약어, 1은 도큐먼트 고유 ID이다.

PUT index2/_doc/1
{
    k1:v1,
    k2:v2,
    ...
}

다이내믹 매핑 (Dynamic Mapping)

ElasticSearch는 데이터 타입을 지정하지 않아도 도큐먼트의 필드와 값을 보고 자동으로 타입을 지정한다. 또한 사용자 입력 실수에 대비해 자동으로 데이터 형변환을 진행한다.

  • 숫자 필드에 문자열 입력 시 숫자로 변환
  • 정수 필드에 소수가 입력되면 소수 자리 무시

CRUD - 조회·수정·삭제(RUD)

-- (R)
-- 도큐먼트 아이디를 이용해 조회
GET index2/_doc/1
 
-- 쿼리 DSL을 이용해 검색
GET index2/_search
 
-- (U) 수정은 비용이 많이 들기 때문에 권장하지 않음
-- _doc id를 이용한 덮어쓰기
PUT index2/_doc/1
{
  "name": "mike2",
  "age": 2,
  "gender": "male2"
}
 
-- update API를 사용한 부분 업데이트
POST index2/_update/1
{
  "doc": {
    "name" : "LEE"
  }
}
 
-- (D)
DELETE index2/_doc/2

응답 메시지 코드

코드상태해결방법
200, 201정상적으로 수행
4xx클라이언트 오류클라이언트에서 문제점 수정
404요청한 리소스가 없음인덱스나 도큐먼트가 존재하는지 확인
405요청 메소드(GET, POST 등)를 지원하지 않음API 사용법 확인
429요청 과부화(busy)재전송, 노드 추가 등
5xx서버 오류ES 로그 확인

벌크 데이터

  • 데이터 CRUD를 할 때는 REST API를 호출해 하나하나 도큐먼트를 요청하는 것보다 벌크(bulk)로 한 번에 요청하는 것이 효과적이다.
  • bulk API는 읽기는 지원하지 않고 CUD만 지원한다.
  • 복수의 JSON 구조를 줄바꿈 문자열로 구분하는 NDJSON 형태이다.
POST _bulk
{"index" : {"_index":"index2", "_id":"4"}}
{"name": "park", "age": 30, "gender": "female"}
{"index" : {"_index":"index2", "_id":"5"}}
{"name": "park2", "age": 32, "gender": "female"}

벌크 데이터 파일 전송

// bulk_test 파일 내용
{"index" : {"_index":"index2", "_id":"4"}}
{"name": "park", "age": 30, "gender": "female"}
{"index" : {"_index":"index2", "_id":"5"}}
{"name": "park2", "age": 32, "gender": "female"}
curl -XPOST http://host.docker.internal:9200/_bulk --data-binary @bulk_test -H 'Content-Type: application/x-ndjson'

매핑, 템플릿, 분석기

매핑 (Mapping)

매핑은 데이터베이스의 스키마 역할을 하며, JSON 데이터를 루씬이 이해할 수 있도록 빠르게 변환하는 역할을 한다.

  • 다이내믹 매핑: ElasticSearch가 자동으로 매핑
    GET index2/_mapping
  • 명시적 매핑: 사용자가 직접 설정. 저장할 데이터를 확실히 알고 있다면 인덱스를 생성할 때 직접 매핑하는 것이 좋다. 단, 이미 정의된 필드를 수정하거나 삭제할 수는 없다.
    PUT index3
    {
        "mappings": {
            "properties": {
                "age": {"type": "short"},
                "name": {"type": "text"},
                "gender": {"type": "keyword"}
            }
        }
    }

text vs keyword

  • text: 전문 검색이 필요한 데이터로, 텍스트 분석기가 텍스트를 작은 단위로 분리한다. 집계나 정렬 시 메모리를 많이 사용한다.
    • 예: "beautiful day"["beautiful", "day"]
  • keyword: 정렬이나 집계에 사용되는 데이터로, 분석을 하지 않고 원문 통째로 인덱싱한다.
    • 예: "beautiful day"["beautiful day"]

멀티 필드 (Multi-field)

멀티 필드는 단일 필드 입력에 대해 여러 하위 필드(keyword, text 동시 사용 등)를 정의하는 기능이다. fields 매핑 파라미터를 사용하며, 전문 검색과 정렬이 동시에 필요한 경우에 유용하다.

PUT multifield_index
{
  "mappings": {
    "properties": {
      "message":{"type": "text"},
      "contents" : {
        "type": "binary",
        "fields": {
          "keyword": {"type": "keyword"}
        }
      }
    }
  }
}
 
GET multifield_index2/_search
{
  "query": {
    "term": {
      "contents.keyword": "day"
    }
  }
}

인덱스 템플릿 (Index Template)

인덱스 템플릿은 주로 설정이 동일한 복수의 인덱스를 만들 때 사용한다. 관리 편의성 및 성능을 위해 인덱스를 파티셔닝하는 경우 해당 인덱스들은 설정이 같아야 하므로, 주로 mappingsetting을 함께 정의한다. beats와 같은 수집 툴에서 ElasticSearch로 데이터를 보낼 때 이 템플릿을 많이 활용한다.

PUT _index_template/test_template
{
  "index_patterns": ["test_*"],
  "priority": 1,
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1
    },
    "mappings": {
      "properties": {
        "name": {"type": "text"},
        "age": {"type": "short"},
        "gender": {"type": "keyword"}
      }
    }
  }
}

다이내믹 템플릿 (Dynamic Template)

다이내믹 템플릿은 매핑을 정확하게 정할 수 없거나 대략적인 데이터 구조만 알고 있을 때 사용하는 방법이다.

PUT dynamic_index1
{
  "mappings": {
    "dynamic_templates": [{
      "my_string_fields" : {
        "match_mapping_type" : "string",
        "mapping" : {"type": "keyword"}
      }
    }]
  }
}

분석기 (Analyzer)

ElasticSearch에서는 전문 검색을 지원하기 위해 역인덱싱(장문의 문자열을 쪼개 나온 토큰을 인덱싱하는 것) 기술을 사용한다. 이를 위해 분석기(Analyzer)를 사용하며, 크게 세 단계로 구성된다.

참고: https://www.elastic.co/guide/en/elasticsearch/reference/current/analyzer-anatomy.html

  1. character filter (옵션): 입력 텍스트를 사전 가공
  2. tokenizer (필수): 텍스트를 토큰 단위로 분리
  3. token filter (옵션): 토큰을 후처리(소문자 변환, 불용어 제거 등)

정리하며

ElasticSearch의 기본 조작인 인덱스·도큐먼트 CRUD부터 벌크 API, 다이내믹/명시적 매핑, 멀티 필드, 인덱스 템플릿, 분석기까지 핵심 개념을 살펴봤다. 인덱스를 생성할 때 명시적 매핑을 잘 설계하는 것이 검색 성능에 직접적인 영향을 미치므로, 운영 환경에서는 다이내믹 매핑보다 명시적 매핑을 우선적으로 고려하는 것이 좋다.