Hybrid 쿼리
Hybrid 쿼리
hybrid 쿼리는 여러 쿼리의 관련성 점수를 주어진 문서에 대한 하나의 점수로 결합할 수 있어요. 하나 이상의 쿼리 목록을 포함하며 각 하위 쿼리에 대해 샤드 수준에서 문서 점수를 독립적으로 계산합니다.
출처: 문서
본문
hybrid 쿼리를 사용하면 여러 쿼리의 관련성 점수를 주어진 문서에 대한 하나의 점수로 결합할 수 있어요. hybrid 쿼리는 하나 이상의 쿼리 목록을 포함하며 각 하위 쿼리에 대해 샤드 수준에서 문서 점수를 독립적으로 계산해요. 중복 계산을 피하기 위해 하위 쿼리 재작성(rewriting)은 코디네이팅 노드 수준에서 수행돼요.
예시 (Example)
hybrid 쿼리 사용법은 Hybrid search의 단계를 따라 배울 수 있어요. 종합적인 예시는 Getting started with semantic and hybrid search를 따르세요.
파라미터 (Parameters)
다음 표는 hybrid 쿼리가 지원하는 모든 최상위 파라미터를 나열해요.
| 파라미터 | 설명 |
|---|---|
queries |
문서를 매칭하는 데 사용되는 하나 이상의 쿼리 절 배열. 문서는 결과에 반환되기 위해 적어도 하나의 쿼리 절과 일치해야 해요. 검색 파이프라인을 적용해 모든 쿼리 절의 관련성 점수를 하나의 점수로 결합해요. 최대 쿼리 절 수는 5개예요. 필수. |
filter |
hybrid 쿼리의 모든 하위 쿼리에 적용할 필터. 필터는 단일 쿼리 객체여야 해요. 여러 필터 조건을 적용하려면 Boolean 쿼리로 결합하세요. 자세한 내용은 Hybrid search with pre-filtering을 참조하세요. |
pagination_depth |
각 하위 쿼리가 각 샤드에서 반환하는 최대 검색 결과 수. 이 값은 검색 파이프라인이 정규화하고 결합하는 문서 집합을 제한하므로, 페이지를 매길 수 있는 깊이와 결과 순서 모두에 영향을 줘요. 유효한 값은 1부터 index.max_result_window 값(기본값 10000)까지의 정수예요. from이 0보다 크면 필수이고, 그렇지 않으면 선택 사항이에요. 제공하지 않으면 각 하위 쿼리는 각 샤드에서 최대 size만큼의 결과를 반환해요. 자세한 내용은 Paginating hybrid query results를 참조하세요. |
Hybrid 쿼리 재점수화 (Rescoring hybrid queries)
2.18 버전에서 도입되었어요.
hybrid 쿼리에서는 rescore 파라미터를 사용할 수 있어요. 하지만 재점수화는 표준 쿼리와 비교해 hybrid 쿼리에서 다르게 동작해요.
표준 쿼리에서는 모든 샤드의 결과가 병합된 후 코디네이팅 노드에서 재점수화가 적용돼요. hybrid 쿼리에서는 정규화 및 결합 파이프라인이 실행되기 전에 각 하위 쿼리의 결과에 재점수화가 샤드 수준에서 독립적으로 적용돼요.
hybrid 쿼리의 재점수화 처리 순서는 다음과 같아요.
- hybrid 쿼리의 각 하위 쿼리가 샤드에서 실행되어 별도의 결과 집합을 생성해요.
- rescore 쿼리가 각 하위 쿼리의 결과에 독립적으로 적용돼요.
- 재점수화된 결과가 코디네이팅 노드로 전송돼요.
- 검색 파이프라인(정규화 프로세서 또는 점수 랭커 프로세서)이 재점수화된 하위 쿼리 점수를 정규화하고 결합해요.
hybrid 쿼리에서 재점수화를 사용할 때는 다음 사항을 주의하세요.
window_size는 결합된 결과가 아니라 각 하위 쿼리의 결과에 개별적으로 적용돼요.- 재점수화와 함께 명시적 정렬을 사용할 수 없어요. hybrid 검색에서 정렬과 rescore 쿼리를 결합하려 하면 OpenSearch는 오류를 반환해요.
- 재점수화는 정규화 프로세서와 점수 랭커 프로세서가 지원하는 모든 점수 기반 및 순위 기반 정규화·결합 기법과 호환돼요.
다음 예시는 두 필드에 걸쳐 키워드 매칭을 결합한 hybrid 검색에서 정확한 구문 "search engine"을 포함한 문서를 부스트하기 위해 match_phrase rescore 쿼리를 사용해요.
POST /my-index/_search?search_pipeline=nlp-search-pipeline
{
"query": {
"hybrid": {
"queries": [
{
"match": {
"title": "search engine"
}
},
{
"match": {
"description": "search engine"
}
}
]
}
},
"rescore": {
"window_size": 50,
"query": {
"rescore_query": {
"match_phrase": {
"title": {
"query": "search engine",
"slop": 2
}
}
},
"query_weight": 0.7,
"rescore_query_weight": 1.2
}
}
}
응답에는 초기 hybrid 쿼리 매칭과 rescore 부스트를 모두 반영한 점수를 가진 문서가 포함돼요.
{
"took": 30,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 0.95,
"hits": [
{
"_index": "my-index",
"_id": "1",
"_score": 0.95,
"_source": {
"title": "Building a search engine",
"description": "A guide to modern search engine architecture"
}
},
{
"_index": "my-index",
"_id": "2",
"_score": 0.67,
"_source": {
"title": "Introduction to search",
"description": "Learn about search engine basics"
}
},
{
"_index": "my-index",
"_id": "3",
"_score": 0.42,
"_source": {
"title": "Database engine tuning",
"description": "How to optimize your search queries"
}
}
]
}
}
이 예시에서 문서 1은 rescore match_phrase 쿼리가 점수를 부스트하므로(제목 필드에 정확한 구문 "search engine"이 포함됨) 가장 높게 순위가 매겨져요. 문서 2는 해당 구문이 description 필드에만 있어서 title에 대한 구문 매칭으로 받는 부스트가 더 작아요. 문서 3은 여러 필드에 걸쳐 개별 용어 "search"와 "engine"은 일치하지만 정확한 구문은 아니므로 가장 작은 부스트를 받아요. rescore 쿼리가 정규화 전에 각 하위 쿼리 결과에 샤드 수준에서 독립적으로 적용되므로, 구문 부스트가 최종 결합 점수에 영향을 줘요.
Hybrid 쿼리에서의 min_score 지원
- 3.5 버전부터
min_score파라미터는 점수 정규화와 결합 이후에 적용돼요._score로 정렬하거나 명시적 정렬 순서를 지정하지 않았을 때만 사용할 수 있어요.min_score를 다른 정렬 기준과 함께 사용하면 요청이 오류가 돼요. - OpenSearch 3.5부터 512개 이상의 샤드를 가진 인덱스에서 hybrid 쿼리를 사용할 수 있어요. OpenSearch는 모든 샤드에서 적절한 점수 정규화를 보장하기 위해 배치 감소(batched reduction)를 자동으로 비활성화해요. 구성은 필요 없어요. 샤드 수가 많은 인덱스에서는 코디네이팅 노드의 메모리 사용량이 더 높을 수 있음에 유의하세요.
_msearch엔드포인트는 배치 감소의 자동 처리를 지원하지 않아요. 많은 샤드에 걸친 hybrid 쿼리가 있는 다중 검색 요청에는 인덱스 패턴 또는 별칭과 함께_search엔드포인트를 사용하세요.
제한 사항 (Limitations)
hybrid 쿼리는 검색 요청의 최상위 쿼리로 설계되었어요. function_score, constant_score, script_score, boosting 같은 다른 복합 또는 래퍼 쿼리 안에 중첩할 수 없어요. 이 제한은 다중 수준 중첩에도 적용돼요. 예를 들어 hybrid 쿼리를 포함하는 function_score 쿼리를 담은 bool 쿼리는 허용되지 않아요. 이런 래퍼 쿼리 안에 hybrid 쿼리를 중첩하면 런타임 오류가 발생하거나 정규화 파이프라인을 조용히 우회할 수 있어요.
hybrid 쿼리는 래퍼 쿼리와 호환되지 않는 특수한 점수 산정 메커니즘을 사용해요. 래퍼 쿼리는 정규화·결합 파이프라인이 올바르게 작동하는 데 필요한 hybrid 쿼리의 하위 쿼리별 점수 수집을 우회하는 다른 내부 스코어러를 사용해요.
hybrid 검색 결과에 점수 부스트 함수를 적용하려면 hybrid 쿼리를 bool 쿼리로 바꾸고 하위 쿼리들을 should 절로 이동하세요. 이 대안은 hybrid 쿼리를 지원하는 모든 OpenSearch 버전에서 작동해요.
예를 들어 다음 쿼리는 지원되지 않아요.
GET /my-index/_search?search_pipeline=my-pipeline
{
"query": {
"function_score": {
"query": {
"hybrid": {
"queries": [
{"match": {"title": "search terms"}},
{"term": {"category": "books"}}
]
}
},
"functions": [{"field_value_factor": {"field": "popularity"}}]
}
}
}
대신 다음 동등한 쿼리를 사용하세요.
GET /my-index/_search
{
"query": {
"function_score": {
"query": {
"bool": {
"should": [
{"match": {"title": "search terms"}},
{"term": {"category": "books"}}
]
}
},
"functions": [{"field_value_factor": {"field": "popularity"}}]
}
}
}
hybrid 쿼리 대신 should 절을 포함한 bool 쿼리를 사용하면 검색 파이프라인의 정규화·결합 프로세서는 적용되지 않아요. 대신 하위 쿼리의 점수는 표준 Boolean 점수 산정(일치 절의 합)으로 결합돼요. 그런 다음 function_score 함수가 결합된 점수에 적용돼요.
Hybrid 쿼리 비활성화 (Disabling hybrid queries)
기본적으로 hybrid 쿼리는 활성화되어 있어요. 클러스터에서 hybrid 쿼리를 비활성화하려면 opensearch.yml에서 plugins.neural_search.hybrid_search_disabled 설정을 true로 설정하세요.