🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Elasticsearch 인덱스와 매핑 기초 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 11. 28. · 19 Views

Elasticsearch 인덱스와 매핑 기초 완벽 가이드

Elasticsearch에서 데이터를 저장하고 검색하기 위한 핵심 개념인 인덱스와 매핑에 대해 알아봅니다. 인덱스 생성부터 동적 매핑, 명시적 매핑, 필드 타입까지 초급 개발자가 꼭 알아야 할 내용을 담았습니다.


목차

  1. 인덱스_생성하기
  2. 동적_매핑_이해
  3. 명시적_매핑_정의
  4. 필드_데이터_타입
  5. text_vs_keyword_차이
  6. 매핑_변경_제약사항

1. 인덱스 생성하기

김개발 씨는 오늘 처음으로 Elasticsearch를 사용하게 되었습니다. MySQL은 테이블을 만들어서 데이터를 저장하는데, Elasticsearch는 어떻게 해야 할까요?

선배가 "일단 인덱스부터 만들어봐"라고 했는데, 인덱스가 대체 무엇인지 막막하기만 합니다.

**인덱스(Index)**는 Elasticsearch에서 데이터를 저장하는 가장 큰 단위입니다. 마치 관계형 데이터베이스의 데이터베이스나 테이블과 비슷한 개념입니다.

인덱스를 생성해야 비로소 문서(Document)를 저장하고 검색할 수 있습니다.

다음 코드를 살펴봅시다.

// Elasticsearch 인덱스 생성 - Node.js 클라이언트 사용
const { Client } = require('@elastic/elasticsearch');
const client = new Client({ node: 'http://localhost:9200' });

// 'products' 인덱스 생성
async function createIndex() {
  const response = await client.indices.create({
    index: 'products',  // 인덱스 이름
    body: {
      settings: {
        number_of_shards: 1,    // 샤드 개수
        number_of_replicas: 1   // 복제본 개수
      }
    }
  });
  console.log('인덱스 생성 완료:', response);
}

김개발 씨는 입사 3개월 차 주니어 개발자입니다. 회사에서 검색 기능 개선 프로젝트에 투입되면서 난생처음 Elasticsearch를 접하게 되었습니다.

MySQL만 사용해봤던 그에게 Elasticsearch는 완전히 새로운 세계였습니다. 선배 개발자 박시니어 씨가 옆자리로 다가왔습니다.

"일단 인덱스부터 만들어야 해. 인덱스가 뭔지 알아?" 김개발 씨는 머뭇거리며 대답했습니다.

"인덱스요? 데이터베이스에서 검색 속도 높이려고 만드는 그 인덱스 말씀이신가요?" 박시니어 씨가 웃으며 고개를 저었습니다.

"비슷하면서도 달라. Elasticsearch에서 인덱스는 데이터를 담는 그릇이야.

MySQL로 치면 테이블이라고 생각하면 돼." 쉽게 비유하자면, 인덱스는 마치 도서관의 서가와 같습니다. 도서관에 책을 보관하려면 먼저 서가가 있어야 하듯이, Elasticsearch에 데이터를 저장하려면 먼저 인덱스가 있어야 합니다.

서가마다 소설, 과학, 역사 등 분류가 다르듯이 인덱스도 저장할 데이터의 성격에 따라 나눕니다. 인덱스를 생성할 때는 몇 가지 설정을 함께 지정할 수 있습니다.

가장 중요한 것이 **샤드(Shard)**와 복제본(Replica) 설정입니다. 샤드는 데이터를 나눠서 저장하는 단위이고, 복제본은 데이터 안정성을 위한 백업입니다.

위의 코드를 살펴보면, 먼저 Elasticsearch 클라이언트를 생성하고 localhost의 9200 포트에 연결합니다. 그다음 client.indices.create 메서드로 인덱스를 생성합니다.

인덱스 이름은 소문자만 사용할 수 있고, 특수문자는 제한됩니다. settings 부분에서 샤드 개수와 복제본 개수를 지정했습니다.

개발 환경에서는 샤드 1개, 복제본 1개면 충분합니다. 프로덕션 환경에서는 데이터 양과 검색 부하에 따라 적절히 조절해야 합니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 쇼핑몰을 운영한다면 상품 정보를 저장하는 products 인덱스, 주문 정보를 저장하는 orders 인덱스, 로그를 저장하는 logs 인덱스처럼 데이터 성격에 따라 분리합니다.

주의할 점이 있습니다. 인덱스 이름에 대문자를 사용하면 오류가 발생합니다.

또한 하이픈(-)이나 언더스코어(_)는 사용 가능하지만, 마침표(.)로 시작하는 이름은 시스템용으로 예약되어 있습니다. 김개발 씨가 고개를 끄덕였습니다.

"아, MySQL의 CREATE TABLE과 비슷한 거군요!" 박시니어 씨가 엄지를 치켜세웠습니다. "맞아, 이제 인덱스에 데이터를 넣을 준비가 된 거야."

실전 팁

💡 - 인덱스 이름은 항상 소문자로 작성하세요

  • 개발 환경에서는 샤드 1개로 시작하고, 프로덕션에서 조절하세요

2. 동적 매핑 이해

인덱스를 만든 김개발 씨가 바로 데이터를 넣어봤습니다. 그런데 신기하게도 필드 구조를 미리 정의하지 않았는데도 데이터가 잘 들어갑니다.

이게 어떻게 가능한 걸까요? Elasticsearch가 알아서 처리해주는 걸까요?

**동적 매핑(Dynamic Mapping)**은 Elasticsearch가 문서를 색인할 때 필드 타입을 자동으로 감지하고 매핑을 생성하는 기능입니다. 마치 스마트한 비서가 서류를 받으면 알아서 분류해주는 것과 같습니다.

편리하지만 의도치 않은 타입이 지정될 수 있어 주의가 필요합니다.

다음 코드를 살펴봅시다.

// 동적 매핑 - 문서 색인 시 자동으로 매핑 생성
async function indexDocument() {
  // 매핑을 정의하지 않고 바로 문서 색인
  await client.index({
    index: 'products',
    body: {
      name: '무선 마우스',        // text + keyword로 자동 매핑
      price: 29000,              // long으로 자동 매핑
      inStock: true,             // boolean으로 자동 매핑
      createdAt: '2024-01-15'    // date로 자동 매핑
    }
  });
}

// 생성된 매핑 확인
async function getMapping() {
  const mapping = await client.indices.getMapping({ index: 'products' });
  console.log(JSON.stringify(mapping, null, 2));
}

김개발 씨는 인덱스를 만들자마자 신이 나서 바로 데이터를 넣어봤습니다. MySQL이었다면 CREATE TABLE로 컬럼과 타입을 먼저 정의해야 했을 텐데, Elasticsearch는 그냥 데이터를 넣으니까 들어갔습니다.

"어? 필드 정의를 안 했는데 어떻게 들어간 거지?" 김개발 씨가 의아해하자 박시니어 씨가 설명해줬습니다.

"그게 바로 동적 매핑이야. Elasticsearch가 똑똑해서 데이터를 보고 알아서 타입을 추론하거든." 동적 매핑은 마치 숙련된 도서관 사서와 같습니다.

새로운 책이 들어오면 사서가 책의 내용을 보고 알아서 분류 번호를 붙여주는 것처럼, Elasticsearch도 들어오는 데이터를 보고 적절한 타입을 부여합니다. Elasticsearch의 동적 매핑 규칙은 명확합니다.

문자열이 들어오면 기본적으로 text 타입과 keyword 서브필드가 함께 생성됩니다. 숫자가 들어오면 long이나 float으로, true나 false는 boolean으로, 날짜 형식의 문자열은 date로 자동 감지됩니다.

위 코드에서 name 필드에 '무선 마우스'를 넣으면 Elasticsearch는 이를 text 타입으로 매핑합니다. price에 29000을 넣으면 long 타입으로, inStock에 true를 넣으면 boolean 타입으로 자동 지정됩니다.

createdAt의 '2024-01-15'는 날짜 형식을 인식해서 date 타입이 됩니다. 하지만 동적 매핑이 항상 완벽하지는 않습니다.

예를 들어 '12345'라는 상품 코드를 넣으면 어떻게 될까요? Elasticsearch는 이를 숫자가 아닌 문자열로 인식합니다.

하지만 '12345'를 따옴표 없이 12345로 넣으면 long 타입이 되어버립니다. 실무에서 흔히 겪는 문제가 있습니다.

처음에 숫자 형태의 ID를 넣었다가 나중에 문자열 형태의 ID가 들어오면 매핑 충돌이 발생합니다. 한번 정해진 매핑은 변경할 수 없기 때문입니다.

동적 매핑은 프로토타입을 빠르게 만들 때 유용합니다. 하지만 프로덕션 환경에서는 의도치 않은 타입 지정을 방지하기 위해 명시적 매핑을 권장합니다.

박시니어 씨가 조언했습니다. "동적 매핑은 편하지만 양날의 검이야.

개발할 때는 써도 되는데, 실제 서비스에서는 매핑을 직접 정의하는 게 안전해." 김개발 씨는 메모장에 꼼꼼히 적어뒀습니다.

실전 팁

💡 - 동적 매핑은 프로토타이핑에 유용하지만 프로덕션에서는 주의하세요

  • getMapping API로 자동 생성된 매핑을 반드시 확인하세요

3. 명시적 매핑 정의

동적 매핑의 한계를 깨달은 김개발 씨는 박시니어 씨에게 물었습니다. "그럼 매핑을 직접 정의하려면 어떻게 해야 하나요?" 박시니어 씨가 화면을 가리키며 말했습니다.

"명시적 매핑을 사용하면 돼. 처음엔 귀찮아 보여도 나중에 엄청 편해."

**명시적 매핑(Explicit Mapping)**은 인덱스를 생성할 때 각 필드의 타입과 속성을 직접 정의하는 방식입니다. 마치 건물을 짓기 전에 설계도를 그리는 것처럼, 데이터 구조를 미리 명확하게 정의합니다.

타입 충돌을 방지하고 검색 성능을 최적화할 수 있습니다.

다음 코드를 살펴봅시다.

// 명시적 매핑으로 인덱스 생성
async function createIndexWithMapping() {
  await client.indices.create({
    index: 'products',
    body: {
      mappings: {
        properties: {
          name: { type: 'text', analyzer: 'standard' },
          productCode: { type: 'keyword' },      // 정확한 일치 검색용
          price: { type: 'integer' },            // 정수형
          description: { type: 'text' },         // 전문 검색용
          category: { type: 'keyword' },         // 필터링, 집계용
          createdAt: { type: 'date', format: 'yyyy-MM-dd' },
          tags: { type: 'keyword' }              // 배열도 같은 타입
        }
      }
    }
  });
}

김개발 씨는 동적 매핑으로 개발하다가 낭패를 본 적이 있습니다. 처음에 상품 코드를 '001'로 넣었는데 나중에 1로 넣으니 타입 충돌이 발생했던 것입니다.

그때부터 명시적 매핑의 중요성을 뼈저리게 느꼈습니다. 명시적 매핑은 마치 집을 짓기 전 설계도를 그리는 것과 같습니다.

설계도 없이 집을 지으면 나중에 방 크기를 바꾸거나 벽을 옮기기 어렵습니다. 마찬가지로 매핑을 미리 정의해두면 데이터 구조가 명확해지고 예상치 못한 문제를 방지할 수 있습니다.

위 코드를 자세히 살펴보겠습니다. mappings 객체 안에 properties를 정의하고, 각 필드별로 타입과 속성을 지정합니다.

name 필드는 text 타입으로 지정하고 analyzer를 standard로 설정했습니다. 이렇게 하면 '무선 마우스'를 '무선'으로도 '마우스'로도 검색할 수 있습니다.

text 타입은 형태소 분석이 되기 때문입니다. productCode는 keyword 타입입니다.

상품 코드는 정확히 일치해야 하므로 형태소 분석이 필요 없습니다. 'PRD-001'을 검색하면 정확히 'PRD-001'만 찾습니다.

price는 integer로 지정했습니다. 동적 매핑이었다면 long이 됐겠지만, 상품 가격에 long까지는 필요 없습니다.

적절한 타입을 선택하면 저장 공간을 절약할 수 있습니다. createdAt 필드는 date 타입으로, format까지 지정했습니다.

'yyyy-MM-dd' 형식만 받겠다고 명시한 것입니다. 다른 형식의 날짜가 들어오면 오류가 발생하므로 데이터 정합성을 유지할 수 있습니다.

tags 필드는 keyword 타입인데, 배열도 저장할 수 있습니다. Elasticsearch에서는 필드에 단일 값이든 배열이든 같은 타입으로 처리합니다.

실무에서 명시적 매핑은 선택이 아닌 필수입니다. 특히 여러 개발자가 함께 작업하는 프로젝트에서는 매핑 문서가 일종의 스키마 역할을 합니다.

새로운 팀원이 와도 매핑만 보면 데이터 구조를 바로 파악할 수 있습니다. 박시니어 씨가 강조했습니다.

"매핑은 한번 정하면 바꾸기 어려워. 처음에 신중하게 설계해야 해." 김개발 씨는 앞으로 모든 인덱스는 명시적 매핑으로 만들겠다고 다짐했습니다.

실전 팁

💡 - 프로덕션 환경에서는 반드시 명시적 매핑을 사용하세요

  • date 타입은 format을 명시하여 데이터 정합성을 유지하세요

4. 필드 데이터 타입

명시적 매핑을 배운 김개발 씨는 새로운 고민에 빠졌습니다. "필드 타입이 너무 많은데, 언제 어떤 걸 써야 하죠?" 박시니어 씨가 화이트보드에 표를 그리기 시작했습니다.

"자주 쓰는 타입만 알면 돼. 정리해줄게."

Elasticsearch는 다양한 필드 데이터 타입을 제공합니다. 문자열에는 text와 keyword, 숫자에는 integer, long, float, double, 날짜에는 date, 논리값에는 boolean이 있습니다.

각 타입의 특성을 이해하고 데이터에 맞는 타입을 선택하는 것이 중요합니다.

다음 코드를 살펴봅시다.

// 주요 필드 데이터 타입 예시
const productMapping = {
  mappings: {
    properties: {
      // 문자열 타입
      title: { type: 'text' },           // 전문 검색용 (형태소 분석)
      sku: { type: 'keyword' },          // 정확 일치용 (분석 안 함)

      // 숫자 타입
      quantity: { type: 'integer' },     // 정수 (-2^31 ~ 2^31-1)
      viewCount: { type: 'long' },       // 큰 정수 (-2^63 ~ 2^63-1)
      rating: { type: 'float' },         // 실수 (32비트)

      // 날짜 및 논리 타입
      publishedAt: { type: 'date' },     // 날짜/시간
      isActive: { type: 'boolean' },     // true/false

      // 객체 및 중첩 타입
      metadata: { type: 'object' },      // 중첩 객체
      reviews: { type: 'nested' }        // 독립적인 중첩 문서
    }
  }
};

김개발 씨는 처음에 모든 문자열을 text로, 모든 숫자를 long으로 지정했습니다. "일단 큰 걸로 하면 안전하지 않을까?"라는 생각이었습니다.

하지만 박시니어 씨는 고개를 저었습니다. "타입 선택도 전략이야.

잘못 고르면 성능이 떨어지거나 원하는 대로 검색이 안 돼." 필드 타입은 마치 옷장의 수납함과 같습니다. 양말은 작은 칸에, 코트는 큰 공간에 넣어야 효율적이듯이, 데이터도 크기와 용도에 맞는 타입을 선택해야 합니다.

먼저 문자열 타입부터 살펴보겠습니다. text와 keyword 두 가지가 있는데, 이 둘의 차이는 다음 장에서 자세히 다룹니다.

지금은 전문 검색에는 text, 정확 일치에는 keyword라고만 기억하면 됩니다. 숫자 타입은 다양합니다.

integer는 일반적인 정수에 적합하고, long은 조회수처럼 매우 큰 숫자에 사용합니다. float은 평점처럼 소수점이 필요할 때, double은 정밀한 계산이 필요할 때 씁니다.

여기서 중요한 점이 있습니다. 무조건 큰 타입을 선택하는 것은 좋지 않습니다.

long이 integer보다 두 배의 저장 공간을 사용합니다. 수백만 개의 문서가 있다면 이 차이가 꽤 커집니다.

date 타입은 날짜와 시간을 저장합니다. 기본적으로 ISO 8601 형식을 인식하지만, format 옵션으로 커스텀 형식도 지정할 수 있습니다.

내부적으로는 밀리초 단위의 타임스탬프로 저장됩니다. boolean 타입은 true와 false만 저장합니다.

문자열 "true"나 숫자 1도 자동으로 변환됩니다. 하지만 명확하게 true/false로 넣는 것이 좋습니다.

object 타입은 중첩된 JSON 객체를 저장합니다. 하지만 주의할 점이 있습니다.

object 타입은 내부적으로 평탄화되어 저장됩니다. 배열 안의 객체들이 서로 연관성을 잃을 수 있습니다.

이럴 때 nested 타입을 사용합니다. nested는 각 객체를 독립적인 문서로 저장해서 객체 간의 관계를 유지합니다.

상품 리뷰처럼 "작성자와 내용이 함께 검색"되어야 할 때 필요합니다. 김개발 씨가 정리했습니다.

"데이터 크기에 맞는 숫자 타입, 검색 방식에 맞는 문자열 타입을 선택하면 되는 거군요." 박시니어 씨가 고개를 끄덕였습니다. "그래, 그리고 가장 중요한 text와 keyword 차이는 다음에 더 자세히 알려줄게."

실전 팁

💡 - 숫자 타입은 데이터 범위에 맞게 선택하여 저장 공간을 절약하세요

  • 객체 배열에서 관계를 유지해야 한다면 object 대신 nested를 사용하세요

5. text vs keyword 차이

박시니어 씨가 김개발 씨에게 퀴즈를 냈습니다. "상품명 '삼성 갤럭시 S24'를 저장했어.

text 타입이면 '갤럭시'로 검색되는데, keyword 타입이면 안 돼. 왜 그럴까?" 김개발 씨는 잠시 고민하다가 손을 들었습니다.

"혹시... 분석 때문인가요?"

textkeyword는 Elasticsearch에서 가장 중요한 문자열 타입입니다. text는 형태소 분석을 거쳐 검색에 최적화되고, keyword는 원본 그대로 저장되어 정확 일치와 정렬, 집계에 사용됩니다.

이 둘의 차이를 이해하는 것이 Elasticsearch 활용의 핵심입니다.

다음 코드를 살펴봅시다.

// text vs keyword 차이 실습
async function textVsKeyword() {
  // 매핑 정의
  await client.indices.create({
    index: 'articles',
    body: {
      mappings: {
        properties: {
          title: { type: 'text' },        // 형태소 분석 O
          category: { type: 'keyword' }   // 형태소 분석 X
        }
      }
    }
  });

  // 문서 색인
  await client.index({
    index: 'articles',
    body: { title: '맛있는 파스타 만들기', category: '요리/레시피' }
  });

  // text 검색 - '파스타'로 검색 가능
  await client.search({ index: 'articles', body: { query: { match: { title: '파스타' } } } });

  // keyword 검색 - 정확히 '요리/레시피'만 검색됨
  await client.search({ index: 'articles', body: { query: { term: { category: '요리/레시피' } } } });
}

김개발 씨는 text와 keyword의 차이를 이해하느라 며칠을 고민했습니다. 둘 다 문자열인데 왜 굳이 나눠놨을까요?

박시니어 씨가 화이트보드에 그림을 그리며 설명하기 시작했습니다. "'맛있는 파스타 만들기'라는 제목이 있다고 해봐.

text 타입으로 저장하면 내부에서 어떻게 될까?" text 타입은 형태소 분석기(Analyzer)를 통해 문장을 단어로 쪼갭니다. '맛있는 파스타 만들기'는 '맛있는', '파스타', '만들기'로 분리되어 저장됩니다.

마치 책의 색인처럼, 각 단어가 어느 문서에 있는지 기록해두는 것입니다. 이렇게 하면 사용자가 '파스타'만 검색해도 해당 문서를 찾을 수 있습니다.

'맛있는 파스타'로 검색해도, '만들기'로 검색해도 찾아집니다. 이것이 **전문 검색(Full-text Search)**의 핵심입니다.

반면 keyword 타입은 원본 문자열을 그대로 저장합니다. '요리/레시피'는 '요리/레시피' 그 자체로 저장됩니다.

분석 과정이 없습니다. keyword로 저장된 필드를 검색할 때는 정확히 '요리/레시피'라고 입력해야 합니다.

'요리'만 입력하면 찾을 수 없습니다. 대소문자도 구분합니다.

'Electronics'와 'electronics'는 다른 값입니다. 그렇다면 keyword는 언제 쓸까요?

카테고리, 태그, 상태값처럼 정확히 일치해야 하는 필드에 적합합니다. 또한 정렬과 집계에도 keyword를 사용해야 합니다.

text 타입은 분석된 토큰 기준으로 정렬되어 원하는 결과가 나오지 않습니다. 실무에서 자주 쓰는 패턴이 있습니다.

하나의 필드에 text와 keyword를 함께 사용하는 멀티 필드(Multi-field) 방식입니다. 상품명으로 전문 검색도 하고, 정확 일치 필터링도 하고 싶을 때 유용합니다.

동적 매핑을 사용하면 문자열 필드에 자동으로 멀티 필드가 생성됩니다. name 필드를 저장하면 name은 text로, name.keyword는 keyword로 생성됩니다.

이건 Elasticsearch의 똑똑한 기본 동작입니다. 김개발 씨가 정리했습니다.

"전문 검색이 필요하면 text, 정확 일치나 정렬/집계가 필요하면 keyword군요." 박시니어 씨가 엄지를 치켜세웠습니다. "정확해!

이걸 모르면 검색 결과가 이상하게 나와서 한참 헤매게 돼."

실전 팁

💡 - 상품명, 본문처럼 검색되어야 하는 필드는 text를 사용하세요

  • 카테고리, 상태, 태그처럼 필터링에 쓰이는 필드는 keyword를 사용하세요

6. 매핑 변경 제약사항

며칠 후, 김개발 씨에게 급한 요청이 들어왔습니다. "상품명 필드를 keyword에서 text로 바꿔주세요." 간단할 거라 생각했는데, 오류가 발생합니다.

"mapper [name] cannot be changed from type [keyword] to [text]." 대체 무슨 일이 일어난 걸까요?

Elasticsearch에서 기존 필드의 타입은 변경할 수 없습니다. 이는 역인덱스 구조의 특성 때문입니다.

마치 이미 출판된 책의 색인을 바꿀 수 없는 것과 같습니다. 타입을 변경하려면 새 인덱스를 만들고 데이터를 재색인해야 합니다.

다음 코드를 살펴봅시다.

// 매핑 변경 시도 - 실패 예시
async function tryChangeMapping() {
  // 이미 keyword로 정의된 필드를 text로 변경 시도
  try {
    await client.indices.putMapping({
      index: 'products',
      body: {
        properties: {
          productCode: { type: 'text' }  // 오류 발생!
        }
      }
    });
  } catch (error) {
    console.log('매핑 변경 불가:', error.message);
  }
}

// 올바른 방법 - 재색인(Reindex)
async function reindexWithNewMapping() {
  // 1. 새 인덱스 생성 (변경된 매핑 적용)
  await client.indices.create({ index: 'products_v2', body: { /* 새 매핑 */ } });

  // 2. 기존 데이터 복사
  await client.reindex({ body: { source: { index: 'products' }, dest: { index: 'products_v2' } } });

  // 3. 별칭(Alias) 전환으로 무중단 변경
  await client.indices.updateAliases({
    body: { actions: [
      { remove: { index: 'products', alias: 'products_alias' } },
      { add: { index: 'products_v2', alias: 'products_alias' } }
    ]}
  });
}

김개발 씨는 당황했습니다. MySQL에서는 ALTER TABLE로 컬럼 타입을 바꿀 수 있었는데, Elasticsearch는 왜 안 되는 걸까요?

박시니어 씨가 설명했습니다. "Elasticsearch는 역인덱스(Inverted Index) 구조를 사용해.

text 타입과 keyword 타입은 역인덱스를 만드는 방식이 완전히 달라. 이미 만들어진 인덱스를 바꾸려면 전체를 다시 만들어야 해." 역인덱스는 마치 책 뒤에 있는 색인과 같습니다.

'사과'라는 단어가 15페이지, 23페이지, 89페이지에 나온다고 기록해두는 것입니다. text 타입은 문장을 단어로 쪼개서 색인을 만들고, keyword는 전체 문자열로 색인을 만듭니다.

이미 출판된 책의 색인 방식을 바꾸려면 책 전체를 다시 찍어야 합니다. Elasticsearch도 마찬가지입니다.

기존 인덱스의 매핑을 바꾸려면 새 인덱스를 만들고 데이터를 다시 색인해야 합니다. 다행히 Elasticsearch는 재색인(Reindex) 기능을 제공합니다.

위 코드처럼 새 인덱스를 원하는 매핑으로 만들고, reindex API로 데이터를 복사하면 됩니다. 하지만 재색인에는 시간이 걸립니다.

수백만 건의 데이터가 있다면 상당히 오래 걸릴 수 있습니다. 이 동안 서비스가 중단되면 안 되겠죠?

이럴 때 **별칭(Alias)**을 사용합니다. 애플리케이션은 products라는 별칭으로 접근하고, 실제로는 products_v1 인덱스를 가리킵니다.

재색인이 완료되면 별칭을 products_v2로 바꿔주면 됩니다. 애플리케이션 코드 변경 없이 무중단으로 매핑을 변경할 수 있습니다.

한 가지 다행인 점이 있습니다. 새 필드 추가는 가능합니다.

기존 필드 타입 변경만 불가능하고, 없던 필드를 새로 추가하는 것은 putMapping API로 할 수 있습니다. 김개발 씨가 한숨을 쉬었습니다.

"그래서 처음에 매핑을 신중하게 설계하라고 하셨군요." 박시니어 씨가 고개를 끄덕였습니다. "맞아.

나중에 바꾸려면 엄청 귀찮아. 처음에 좀 더 시간 들여서 제대로 설계하는 게 훨씬 나아." 김개발 씨는 앞으로 인덱스를 만들 때 매핑을 더욱 신중하게 결정하겠다고 다짐했습니다.

그리고 혹시 모를 변경에 대비해 항상 별칭을 사용하기로 했습니다.

실전 팁

💡 - 인덱스 생성 전 매핑을 충분히 검토하세요, 나중에 바꾸기 어렵습니다

  • 처음부터 별칭(Alias)을 사용하면 재색인 시 무중단 전환이 가능합니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Elasticsearch#Index#Mapping#TextField#KeywordField#Elasticsearch,Search,Backend

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.