본문으로 건너뛰기
김신건의 로그

[Search] ES Vector Search: kNN, ELSER, RAG

· 수정 · 📖 약 2분 · 640자/단어 #elasticsearch #vector-search #knn #elser #semantic #rag #ai
ES vector search, dense_vector, sparse_vector, kNN search, HNSW, ELSER, Elastic Learned Sparse EncodeR, hybrid search, RRF, semantic_text

정의

ES 의 벡터 검색 = 임베딩 기반 의미 검색. kNN (Approximate Nearest Neighbor) 으로 수억 벡터 안에서 가까운 K개 찾기.

2026 시점의 ES 위치: 전통 BM25 + dense vector + sparse vector + hybrid 모두 지원하는 통합 검색 엔진.

3가지 벡터 표현

flowchart TB
    Q[Vector 표현]
    Q --> Dense["dense_vector<br/>(예: 384, 768, 1536 차원)"]
    Q --> Sparse["sparse_vector / ELSER<br/>(term:weight 맵)"]
    Q --> Hybrid["Hybrid<br/>(BM25 + Vector RRF)"]
종류의미
Dense모든 차원 채워진 vector (OpenAI, Cohere, BGE 등)
Sparse대부분 0, 의미있는 term 만 가중치
Hybrid키워드 + 의미 결합

Dense Vector (전통 임베딩)

PUT /docs
{
  "mappings": {
    "properties": {
      "content": { "type": "text" },
      "embedding": {
        "type": "dense_vector",
        "dims": 384,
        "index": true,
        "similarity": "cosine",
        "index_options": {
          "type": "hnsw",
          "m": 16,
          "ef_construction": 100
        }
      }
    }
  }
}
옵션의미
dims차원 (모델 의존)
similaritycosine, dot_product, l2_norm, max_inner_product
typehnsw (기본), flat, int8_hnsw, int4_hnsw, bbq_hnsw (8.15+)
mHNSW 노드의 연결 수
ef_construction빌드 시 후보군

Quantization (메모리 절감)

옵션메모리 (vs float32)정확도
hnsw (float32)100%기준
int8_hnsw25%95%+ recall
int4_hnsw (8.15+)12.5%90%+ recall
bbq_hnsw (Better Binary Quantization, 9.x)3%80%+ recall

IMPORTANT

2026 시점 기본 = int8_hnsw. 메모리 1/4 + 거의 같은 정확도. 대용량 (수억+) = BBQ.

GET /docs/_search
{
  "knn": {
    "field": "embedding",
    "query_vector": [0.1, 0.2, ..., 0.05],
    "k": 10,
    "num_candidates": 100
  }
}
파라미터의미
k반환할 수
num_candidates후보 풀 (정확도 vs 속도)
filterbool query 와 결합
boosthybrid 시 가중치

ELSER (Elastic Learned Sparse EncodeR)

flowchart LR
    Text["query / doc"] --> ELSER[ELSER 모델]
    ELSER --> Sparse["{ ml.tokens: {<br/> 'rabbit': 1.2,<br/> 'hat': 0.8,<br/> 'magic': 0.4<br/>} }"]
    Sparse --> Index[(ES sparse_vector)]
    Sparse --> Score[BM25-like score on sparse vector]
  • Elastic 자체 모델. 8.8+ stable.
  • term 단위 가중치 (sparse).
  • 별도 GPU 없이 CPU 추론 가능.
  • 영문 우수. 9.x 에서 multilingual 진입.
PUT /docs
{
  "mappings": {
    "properties": {
      "content_expanded": {
        "type": "sparse_vector"
      }
    }
  }
}

POST /_ml/trained_models/.elser_model_2/deployment/_start

PUT /_ingest/pipeline/elser-pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": ".elser_model_2",
        "input_output": [{ "input_field": "content", "output_field": "content_expanded" }]
      }
    }
  ]
}

쿼리:

{
  "query": {
    "sparse_vector": {
      "field": "content_expanded",
      "inference_id": ".elser_model_2",
      "query": "토끼가 마술 모자에서 나오다"
    }
  }
}

semantic_text (8.15+, 추천)

PUT /docs
{
  "mappings": {
    "properties": {
      "content": {
        "type": "semantic_text",
        "inference_id": "my-elser-or-openai-or-cohere"
      }
    }
  }
}

위 한 필드면 자동 청크 + 임베딩 + 인덱싱 + 쿼리. 별도 ingest pipeline 불필요. 2026 시점 권장 접근.

Hybrid Search + RRF (Reciprocal Rank Fusion)

GET /docs/_search
{
  "retriever": {
    "rrf": {
      "retrievers": [
        { "standard": { "query": { "match": { "content": "토끼 모자" } } } },
        { "knn": { "field": "embedding", "query_vector_builder": { "text_embedding": { "model_id": "...", "model_text": "토끼 모자" } }, "k": 50, "num_candidates": 200 } }
      ],
      "rank_window_size": 50,
      "rank_constant": 60
    }
  }
}

키워드 (BM25) + 의미 (벡터) 두 ranking 을 RRF 로 결합. 최강 패턴.

자세한 RRF 공식:

RRF_score(d) = Σ 1 / (k + rank_i(d))
출처rankRRF (k=60)
BM2511/61 ≈ 0.0164
BM25101/70 ≈ 0.0143
Vector11/61
둘 다 top합산약 0.033

Inference API (외부 LLM 통합)

PUT _inference/text_embedding/my-openai
{
  "service": "openai",
  "service_settings": {
    "api_key": "sk-...",
    "model_id": "text-embedding-3-small"
  }
}

PUT _inference/text_embedding/my-cohere
{
  "service": "cohere",
  "service_settings": { "api_key": "...", "model_id": "embed-multilingual-v3.0" }
}

OpenAI, Cohere, HuggingFace, Bedrock, Azure AI, Anthropic 등 공통 인터페이스.

RAG 패턴

flowchart LR
    User[User query] --> Embed[Inference API:<br/>embedding]
    Embed --> Hybrid["Hybrid Retriever<br/>(BM25 + vector + RRF)"]
    Hybrid -->|top-K chunks| Prompt[LLM prompt 구성]
    Prompt --> LLM[OpenAI / Claude / Llama]
    LLM --> Answer

ES vs 전용 Vector DB

ESPineconeMilvusWeaviateQdrant
BM25 + Vector최고보통보통
Filter + kNN보통
Operation익숙 (ES 운영자)managed onlyself-host 가능둘 다둘 다
가격 (자체)무료비쌈무료무료무료

IMPORTANT

기존에 ES 운영 중 = vector store 도 ES 로 통합 추천. 별도 vector DB 도입 비용 > ES 의 vector 기능 한계.

흔한 함정

WARNING

  1. 차원 불일치 = mapping 의 dims 와 실제 vector 길이 다름 → 인덱싱 거절.
  2. HNSW 빌드 메모리 = 큰 인덱스의 빌드 시간이 수십 분 ~ 시간. heap 충분.
  3. scoring 단위 다름 = BM25 와 vector score 의 절대값 비교 무의미. RRF 가 답.
  4. dense 만 사용 = 키워드 매치 (정확한 product code 등) 못 잡음. hybrid.

관련 위키

이 글의 용어 (4개)
[Redis] Vector Search: HNSW, SVS-VAMANA, Semantic Cachedatabase-internals
정의 Vector Search 는 임베딩 벡터의 거리/유사도 기준으로 근접한 K 개 를 찾는 검색. Redis 는 RediSearch 모듈 (Redis 8 부터는 코어) 과 Va…
[Search] ES Aggregations: metric, bucket, pipelinesearch
정의 Aggregations (aggs) = ES 의 집계 분석. SQL 의 GROUP BY + 함수 + window. 검색 결과 또는 전체 위에서. 3가지 카테고리 Metric…
[Search] ES Query: must / should / filter / must_notsearch
정의 ES 의 Query DSL = JSON 기반 표현력 풍부한 쿼리 언어. bool query + leaf query 의 조합. bool query: 4가지 절 | 절 | AN…
[Search] ES Relevance Scoring: BM25, TF-IDF, function_scoresearch
정의 Relevance Score ( ) = 쿼리와 문서의 매칭 강도. ES 7+ 의 기본은 BM25 (TF-IDF 의 발전형). BM25 공식 | 부분 | 의미 | |---|-…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기