OpenSearchMetadataRetriever
OpenSearchMetadataRetriever
OpenSearch Document Store에 저장된 문서의 메타데이터 필드를 검색·순위화하고, 일치하는 메타데이터 값을 돌려주는 컴포넌트예요.
출처: 문서
본문
OpenSearchMetadataRetriever는 OpenSearchDocumentStore에 저장된 문서의 메타데이터를 검색하고, 문서 자체가 아니라 일치하는 메타데이터 값을 돌려줘요. 메타데이터 자체가 답인 경우 유용한데, 예를 들어 부분 검색어와 일치하는 카테고리·태그 목록을 만들거나, 메타데이터 자동완성을 만들거나, 문서 내용을 가져오지 않고 인덱스의 구조화된 측면을 드러낼 때가 그래요.
다른 OpenSearch retriever(OpenSearchBM25Retriever, OpenSearchEmbeddingRetriever, OpenSearchHybridRetriever)와 달리 이 컴포넌트는 Document 객체를 돌려주지 않아요. 출력은 metadata 아래의 목록인데, 각 항목은 metadata_fields에 나열한 필드만 담은 사전이에요. 문서 내용과 다른 메타데이터는 결과에서 제외돼요.
이 Retriever는 두 가지 검색 모드를 지원해요.
strict는 설정한 메타데이터 필드에 접두사(prefix)와 와일드카드 매칭을 사용해요.fuzzy(기본값)는dis_max쿼리로 퍼지 매칭을 사용해서 오타와 부분 일치를 허용해요.
두 모드 모두 후보 문서는 서버 쪽에서 문자 n-gram의 Jaccard 유사도(jaccard_n 파라미터가 n-gram 크기를 제어)로 점수를 매기고, 정확히 일치하면 exact_match_weight로 제어되는 추가 가중치를 받아요. OpenSearch에서 최대 1000개의 히트를 가져와 상위 top_k 결과를 돌려줘요.
동기 run 메서드와 비동기 run_async 메서드가 모두 같은 파라미터로 제공돼요.
필드 유형
매칭 엔진은 OpenSearch가 텍스트나 키워드 값으로 인덱싱하는 메타데이터 필드에서만 동작해요. 숫자·불리언·비문자열 배열 필드는 접두사·와일드카드·전문 매칭이 적용되지 않으므로 검색 대상이 될 수 없어요. 문자열과 숫자를 섞은 목록 같은 혼합 유형 필드도 지원되지 않아요.
설치
Docker가 설정되어 있다면 OpenSearch를 돌리는 가장 쉬운 방법은 Docker 이미지를 받아 실행하는 거예요.
docker pull opensearchproject/opensearch:3
docker run -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" -e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password>" opensearchproject/opensearch:3
대안으로 OpenSearch integration GitHub에 가서 제공된 docker-compose.yml로 Docker 컨테이너를 시작할 수 있어요.
docker compose up
실행 중인 OpenSearch 인스턴스가 준비되면 opensearch-haystack 통합을 설치해요.
pip install opensearch-haystack
더 알아보기 (Learn more)
단독으로 쓰기
이 Retriever는 인덱싱된 문서가 있는 OpenSearchDocumentStore가 필요해요. 아래 예제는 간단한 카테고리 메타데이터가 있는 문서 세 개를 쓰고 category와 status 필드를 조회해요.
from haystack import Document
from haystack_integrations.components.retrievers.opensearch import (
OpenSearchMetadataRetriever,
)
from haystack_integrations.document_stores.opensearch import OpenSearchDocumentStore
from haystack.document_stores.types import DuplicatePolicy
document_store = OpenSearchDocumentStore(
hosts="http://localhost:9200",
index="my_index",
use_ssl=True,
verify_certs=False,
http_auth=("admin", "<custom-admin-password>"),
)
documents = [
Document(
content="Python programming guide",
meta={
"category": "Python",
"status": "active",
"priority": 1,
"author": "John Doe",
},
),
Document(
content="Java tutorial",
meta={
"category": "Java",
"status": "active",
"priority": 2,
"author": "Jane Smith",
},
),
Document(
content="Python advanced topics",
meta={
"category": "Python",
"status": "inactive",
"priority": 3,
"author": "John Doe",
},
),
]
document_store.write_documents(documents=documents, policy=DuplicatePolicy.SKIP)
retriever = OpenSearchMetadataRetriever(
document_store=document_store,
metadata_fields=["category", "status"],
mode="strict",
top_k=10,
)
result = retriever.run(query="Python")
print(result)
# {
# "metadata": [
# {"category": "Python", "status": "active"},
# {"category": "Python", "status": "inactive"},
# ]
# }
metadata_fields에 나열한 필드만 각 결과 사전에 나타나요. author 메타데이터와 문서 내용은 제외돼요.
이 예제는 mode="strict"를 사용해서 검색어와 일치하는 문서만 돌려줘요. 기본 fuzzy 모드와 어떻게 다른지는 Strict mode를 참고하세요.
다중 파트 쿼리
query 문자열은 여러 개의 쉼표로 구분된 파트를 포함할 수 있어요. 각 파트는 metadata_fields에 나열된 모든 필드에서 검색되고, 여러 파트와 일치하는 문서가 더 높게 순위화돼요(exact_match_weight로 제어).
result = retriever.run(query="Python, active")
# Returns the metadata of documents matching either part, with the documents that
# match both "Python" and "active" ranked first.
Strict 모드
기본적으로 Retriever는 오타와 부분 일치를 허용하는 fuzzy 모드로 동작해요. 편집 거리 허용 없이 접두사나 와일드카드 매칭만 원하는 조회라면 strict로 전환하세요.
retriever = OpenSearchMetadataRetriever(
document_store=document_store,
metadata_fields=["category"],
mode="strict",
)
result = retriever.run(query="Pyth")
# Matches "Python" through prefix matching, but not transposed-letter variants.
퍼지 모드 파라미터(fuzziness, prefix_length, max_expansions, tie_breaker)는 mode="fuzzy"일 때만 적용돼요.
필터와 함께 쓰기
점수 매기기 전에 후보 집합을 좁히려면 실행 시점에 표준 Haystack filters를 넘길 수 있어요. 필터는 bool filter 컨텍스트에서 적용되므로 점수에는 영향을 주지 않고 일치하지 않는 문서만 제외해요.
result = retriever.run(
query="Python",
filters={"field": "status", "operator": "==", "value": "active"},
)
비동기 실행
동기·비동기 컴포넌트가 섞인 파이프라인을 위해 Retriever는 같은 시그니처의 run_async를 제공해요.
result = await retriever.run_async(query="Python, active")
오류 처리
기본적으로 실패한 OpenSearch 요청은 예외를 발생시켜요. 실패를 빈 결과로 처리하고 싶다면 — 예를 들어 Retriever가 관대한 API 뒤에 있을 때 — raise_on_failure=False로 컴포넌트를 초기화하세요. 그러면 오류는 경고로 기록되고 metadata는 빈 목록으로 반환돼요.