Mapping

Mapping 카테고리의 모든 포스트 - 한국어

3개의 포스트

🎯 매핑 설계 잘하는 팁 & 전략

이 문서는 Elasticsearch에서 매핑(mapping)을 효율적으로 설계하기 위한 팁과 개념들
http://localhost:9200/contents 기준으로 설명합니다.


1. 🎯 매핑 설계 잘하는 팁

🧹 불필요한 필드 제거

  • 저장할 필요가 없는 데이터는 매핑 자체를 하지 않거나 _source에서 제외
  • 검색/필터링/집계에 쓰이지 않는 데이터는 제외하는 것이 성능에 유리

🧷 타입 명확히 지정

데이터 예시적절한 타입
날짜date
정수integer
가격float
이메일, URLkeyword
본문, 설명, 제목text

🚫 동적 매핑(auto mapping) 주의

  • 설정하지 않으면 자동으로 text + keyword로 매핑됨 → 원치 않는 분석기 적용 가능성
  • 명시적인 매핑 정의 권장

2. ⚖️ text vs keyword

항목textkeyword
분석 여부분석됨 (tokenizer, filter 적용)분석되지 않음 (전체값 그대로)
검색 목적전문(full-text) 검색정확한 일치, 집계/정렬/필터용
예시 필드제목, 내용, 댓글ID, 이메일, 태그, 카테고리

3. 🔀 multi-field 전략

🧠 하나의 필드를 여러 방식으로 활용

예: title 필드를 검색도 하고, 정렬/집계도 하려면?

🚨 실전 매핑 실수 모음

이 문서는 Elasticsearch를 사용할 때 자주 발생하는 매핑 설계 실수 사례들을 정리한 가이드입니다.
실수를 피하기 위한 베스트 프랙티스도 함께 소개합니다.


1. ❌ keyword 필드에 match 사용

문제 설명

keyword 필드는 분석되지 않은 문자열이기 때문에 match 쿼리로는 동작하지 않음.

"match": {
  "status": "published"  // keyword 필드일 경우 동작 X
}

해결 방법

  • match 대신 term 쿼리를 사용해야 함
"term": {
  "status": "published"
}

2. ❌ text 필드로 정렬

문제 설명

text 필드는 분석된 문자열이기 때문에 정렬이 불가능하거나 성능이 매우 나쁨.

🛠️ 매핑 + Analyzer + 검색 쿼리 종합 실습

이 문서는 Elasticsearch에서 posts 인덱스를 대상으로
매핑 설계, custom analyzer 구성, 검색 쿼리 실습을 종합적으로 연습하기 위한 실전 예제입니다.


1. 🎯 목표 요약

  • 커스텀 analyzer를 적용한 posts 인덱스 생성
  • title, tags, content 필드를 적절히 text/keyword로 구성
  • 검색 쿼리에서 match, filter, sort, search_after 등 실제 활용

2. ⚙️ 커스텀 Analyzer + 매핑 예제

PUT http://localhost:9200/posts
{
  "settings": {
    "analysis": {
      "tokenizer": {
        "my_nori_tokenizer": {
          "type": "nori_tokenizer",
          "decompound_mode": "mixed"
        }
      },
      "filter": {
        "my_pos_filter": {
          "type": "nori_part_of_speech",
          "stoptags": ["E", "IC", "J"]
        },
        "my_stop_filter": {
          "type": "stop",
          "stopwords": ["은", "는", "이", "가"]
        }
      },
      "analyzer": {
        "my_korean_analyzer": {
          "type": "custom",
          "tokenizer": "my_nori_tokenizer",
          "filter": [
            "lowercase",
            "my_pos_filter",
            "my_stop_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "my_korean_analyzer",
        "fields": {
          "raw": { "type": "keyword" }
        }
      },
      "tags": {
        "type": "keyword"
      },
      "content": {
        "type": "text",
        "analyzer": "my_korean_analyzer"
      },
      "author": {
        "type": "keyword"
      },
      "created_at": {
        "type": "date"
      }
    }
  }
}

3. 📦 예시 문서 삽입 (Bulk API)

POST http://localhost:9200/posts/_bulk
{ "index": {} }
{ "title": "카카오페이 서비스 출시", "tags": ["fintech", "kakao"], "content": "카카오의 새로운 간편결제 서비스가 시작되었습니다.", "author": "alice", "created_at": "2024-01-01T10:00:00Z" }
{ "index": {} }
{ "title": "네이버 지도 업그레이드", "tags": ["map", "naver"], "content": "지도 검색이 더 빠르고 정확해졌습니다.", "author": "bob", "created_at": "2024-02-15T12:30:00Z" }
{ "index": {} }
{ "title": "구글 검색 AI 도입", "tags": ["ai", "google"], "content": "AI로 더 똑똑한 검색이 가능해졌습니다.", "author": "charlie", "created_at": "2024-03-10T15:00:00Z" }

4. 🔍 검색 쿼리 예제

🎯 4-1. 카카오를 포함하고 fintech 태그를 가진 문서 검색

POST http://localhost:9200/posts/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "content": "카카오" } }
      ],
      "filter": [
        { "term": { "tags": "fintech" } }
      ]
    }
  }
}

🧭 4-2. 정렬 + search_after를 사용한 페이징 검색

POST http://localhost:9200/posts/_search
{
  "size": 2,
  "query": {
    "match_all": {}
  },
  "sort": [
    { "created_at": "desc" },
    { "_id": "asc" }
  ],
  "search_after": ["2024-01-01T10:00:00Z", "doc_id_2"]
}

🔍 4-3. title 정렬 (multi-field 사용)

POST http://localhost:9200/posts/_search
{
  "query": {
    "match": {
      "title": "검색"
    }
  },
  "sort": [
    { "title.raw": "asc" }
  ]
}

✅ 요약

항목설명
custom analyzer 설정nori tokenizer + 불용어 + 품사 필터 적용
multi-field 구성title은 text + keyword 함께 사용 (raw 정렬용)
검색 쿼리 활용match, filter, sort, search_after 조합
Bulk 삽입대량 데이터 테스트를 위한 빠른 삽입