StructArray를 활용한 하이브리드 검색
이 페이지를 사용하여 StructArray 벡터 검색을 다른 벡터 검색과 결합하여 하나의 하이브리드 검색 요청으로 수행할 수 있습니다. StructArray 하이브리드 검색은 결합하는 AnnSearchRequest 객체에 따라 엔티티 수준 결과 또는 요소 수준 결과를 반환할 수 있습니다.
이 페이지에서는 ‘StructArray 필드 생성’의 tech_articles 컬렉션을 사용합니다. 이 컬렉션에는 title_vector 라는 최상위 벡터 필드와 chunks 라는 StructArray 필드가 있습니다. chunks[emb_list_vector] 하위 필드는 EmbeddingList 검색을 위해 인덱싱되어 있으며, chunks[emb] 는 요소 수준 검색을 위해 인덱싱되어 있습니다.
StructArray에 하이브리드 검색이 적용되는 방식
AnnSearchRequest 조합 | 최종 후보 범위 | 결과 동작 | element_scope |
|---|---|---|---|
| 컬렉션 수준 벡터 필드 + StructArray EmbeddingList 하위 필드 | 엔티티 수준 | 최종 후보는 기본 키를 기준으로 키가 지정됩니다. | 사용하지 마십시오. |
| 컬렉션 수준 벡터 필드 + StructArray 요소 수준 하위 필드 | 엔티티 수준 | 요소 수준 히트는 하이브리드 재순위 지정 전에 엔티티 수준 후보로 통합됩니다. | StructArray 요소 수준 AnnSearchRequest 의 선택적 축소 구성. |
| 동일한 StructArray 필드 아래에 있는 여러 요소 수준 하위 필드 | 요소 수준 | 최종 후보는 기본 키와 Struct 요소 오프셋을 조합하여 키로 지정됩니다. | 사용하지 마십시오. |
| 서로 다른 StructArray 필드 아래에 있는 요소 수준 하위 필드 | 엔티티 수준 | 요소 오프셋은 식별자를 공유하지 않으므로, 재순위 지정 전에 각 StructArray 요소 수준 AnnSearchRequest 이 접힙니다. | 각 StructArray 요소 수준 AnnSearchRequest 에 대한 선택적 축소 구성. |
경고
element_scope 는 동일한 구조가 아닌 요소 수준 하이브리드 검색에서 StructArray 요소 수준 AnnSearchRequest 객체에 대한 축소 구성을 설정할 때만 사용하십시오. EmbeddingList 요청, 컬렉션 수준 벡터 요청 또는 동일한 StructArray 요소 수준 하이브리드 검색에는 사용하지 마십시오.
시작하기 전에
하이브리드 검색을 실행하기 전에 컬렉션, 데이터 및 인덱스를 준비하십시오.
| 필수 조건 | 세부 정보 |
|---|---|
| StructArray 필드 | 컬렉션에 chunks 와 같은 StructArray 필드가 포함되어 있습니다. |
| 벡터 하위 필드 | EmbeddingList 검색과 요소 수준 검색에는 별도의 벡터 하위 필드를 사용하십시오. |
| 지수 | chunks[emb_list_vector] MAX_SIM* 메트릭을 사용합니다. 는 , 또는 와 같은 일반 벡터 메트릭을 사용합니다. chunks[emb] COSINE IP L2 |
| 재순위 지정기 | RRFRanker 와 같은 하이브리드 재순위 지정기나 애플리케이션에서 지원하는 다른 재순위 지정기를 선택하십시오. |
인덱스 설정에 대해서는 인덱스 StructArray 필드를 참조하십시오.
EmbeddingList 요청을 사용하여 하이브리드 검색 실행
하이브리드 검색에서 StructArray 벡터 하위 필드에 대한 EmbeddingList 검색은 엔티티 수준입니다. 이는 엔티티 수준 벡터 검색 요청과 유사하게 작동하며, 일치하는 단일 Struct 요소 오프셋을 반환하지 않습니다.
from pymilvus import AnnSearchRequest, MilvusClient, RRFRanker
from pymilvus.client.embedding_list import EmbeddingList
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query_vector = [0.19, 0.24, 0.30, 0.37]
query_list = EmbeddingList()
query_list.add([0.12, 0.21, 0.32, 0.44])
query_list.add([0.18, 0.23, 0.29, 0.36])
title_req = AnnSearchRequest(
data=[query_vector],
anns_field="title_vector",
limit=10,
)
chunk_list_req = AnnSearchRequest(
data=[query_list],
anns_field="chunks[emb_list_vector]",
limit=10,
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[title_req, chunk_list_req],
ranker=RRFRanker(),
limit=5,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
],
)
이 예제에서 두 AnnSearchRequest 객체 모두 엔티티 수준 후보를 생성합니다. 최종 결과는 상위 엔티티의 기본 키를 키로 합니다. EmbeddingList 요청에 element_scope 를 추가하지 마십시오.
동일 StructArray 요소 수준 하이브리드 검색 실행
모든 AnnSearchRequest 객체가 동일한 StructArray 필드 하위의 요소 수준 벡터 하위 필드를 대상으로 하는 경우, 하이브리드 검색은 재순위를 통해 요소 수준 후보를 유지할 수 있습니다. 이는 최종 결과가 요소 수준으로 유지되는 유일한 StructArray 하이브리드 모드입니다.
다음 예제는 chunks StructArray 필드에 chunks[emb] 및 chunks[code_emb] 라는 두 개의 요소 수준 벡터 하위 필드가 있으며, 둘 다 일반 벡터 메트릭을 사용한다고 가정합니다.
index_chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
limit=10,
expr='element_filter(chunks, $[section] == "index")',
)
code_chunk_req = AnnSearchRequest(
data=[code_query_vector],
anns_field="chunks[code_emb]",
limit=10,
expr='element_filter(chunks, $[has_code] == true)',
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[index_chunk_req, code_chunk_req],
ranker=RRFRanker(),
limit=5,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
for hits in results:
for hit in hits:
print(
"doc_id:", hit["id"],
"distance:", hit["distance"],
"offset:", hit.get("offset"),
"entity:", hit["entity"],
)
두 AnnSearchRequest 객체 모두 chunks 아래의 벡터 하위 필드를 검색합니다. 동일한 0을 기준으로 하는 오프셋은 동일한 Struct 요소를 가리키므로, 하이브리드 재순위 지정기는 요소 후보를 직접 순위 지정할 수 있습니다. 이 모드에서는 엔티티 수준 병합이 수행되지 않으므로 element_scope 을 설정하지 마십시오.
엔티티 수준 하이브리드 검색을 위한 요소 수준 히트 축소
하이브리드 검색에서 StructArray 요소 수준의 AnnSearchRequest 가 컬렉션 수준의 벡터 요청, EmbeddingList 요청 또는 다른 StructArray 필드 하위의 요소 수준 요청과 혼합되는 경우, 최종 후보 범위는 엔티티 수준이 됩니다. 이 경우, 각 StructArray 요소 수준의 AnnSearchRequest 는 하이브리드 재순위 지정 전에 엔티티 수준 후보로 통합됩니다.
동일한 엔티티에서 일치된 여러 요소가 어떻게 통합될지 제어해야 할 때는 StructArray 요소 수준 AnnSearchRequest 의 params 내부에서 element_scope 를 사용하십시오.
title_req = AnnSearchRequest(
data=[query_vector],
anns_field="title_vector",
limit=10,
)
chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
param={
"params": {
"element_scope": {
"collapse": {
"strategy": "topk_sum",
"topk": 3,
},
},
},
},
limit=30,
expr='element_filter(chunks, $[quality_score] > 0.8)',
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[title_req, chunk_req],
ranker=RRFRanker(),
limit=5,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
이 예제에서 ` title_req `는 엔티티 수준이므로, 최종 하이브리드 결과도 엔티티 수준이 됩니다. ` chunk_req ` 요청은 먼저 ` chunks[emb]`에서 요소 히트를 반환한 다음, 동일한 엔티티에서 반환된 요소들을 합쳐 가장 높은 점수를 받은 3개의 요소 점수를 합산하여 축소합니다. 엔티티 수준 축소가 필요한데 ` element_scope `가 생략된 경우, 축소 전략은 기본적으로 ` max`로 설정됩니다.
합치기 전략 선택
| 전략 | 동작 | topk | 지표 요구 사항 |
|---|---|---|---|
max | 엔티티에 대해 반환된 요소 중 가장 높은 점수를 유지합니다. | 허용되지 않음. | 지원되는 모든 정규 벡터 메트릭. |
sum | 엔티티에 대해 반환된 모든 요소 점수를 합산합니다. | 허용되지 않음. | IP 이나 COSINE 과 같이 양의 상관관계를 갖는 메트릭만 허용됩니다. |
avg | 엔티티에 대해 반환된 모든 요소 점수의 평균을 구합니다. | 허용되지 않습니다. | 지원되는 모든 정규 벡터 메트릭. |
topk_sum | 엔티티에 대해 반환된 요소 점수 중 가장 높은 K 점수의 합계를 구합니다. | 필수이며 양수여야 합니다. | IP 이나 COSINE 과 같이 양의 상관 관계가 있는 메트릭만 사용할 수 있습니다. |
topk_avg | 엔티티에 대해 반환된 요소 점수 중 가장 높은 점수 K 의 평균을 구합니다. | 필수 항목이며 양수여야 합니다. | 지원되는 모든 정규 벡터 메트릭. |
Collapse는 해당 StructArray 요소 수준 AnnSearchRequest 에 의해 반환된 요소 히트만 사용합니다. ANN 검색 후 엔티티의 모든 Struct 요소를 스캔하지는 않습니다. Collapse에 사용할 요소를 확보할 수 있도록 요청 limit 를 충분히 높게 설정하십시오.
필터, 범위 검색 및 그룹화 추가
벡터 검색에 참여하는 동일한 Struct 요소에 스칼라 조건이 적용되어야 하는 경우, StructArray 요소 수준 AnnSearchRequest 에 element_filter 를 연결할 수 있습니다. 또한 상위 엔티티 조건의 경우 hybrid_search() 에 대한 최상위 filter 를 사용할 수도 있습니다.
StructArray 요소 수준 벡터 필드는 하이브리드 검색에서 범위 검색을 지원합니다. 요소 수준 AnnSearchRequest 에 radius 를 추가하고, 선택적으로 range_filter 를 추가하십시오. EmbeddingList 수준 StructArray 요청은 범위 검색을 지원하지 않습니다.
요소 수준 하이브리드 그룹화는 모든 ` AnnSearchRequest ` 객체가 동일한 `StructArray` 필드 하위의 요소 수준 벡터 필드를 대상으로 할 때만 지원되며, ` group_by_field `는 기본 키여야 합니다. 요청에 컬렉션 수준 벡터 필드, 서로 다른 `StructArray` 필드 또는 `EmbeddingList` 수준 요청이 혼합된 경우에는 하이브리드 그룹화가 지원되지 않습니다. 범위 검색과 그룹화를 함께 사용하지 마십시오.
하이브리드 결과 해석
| 최종 후보 범위 | 결과 키 | 오프셋 동작 | 발생 시점 |
|---|---|---|---|
| 엔티티 수준 | 기본 키. | 최종 결과에 요소 오프셋이 없습니다. | 하이브리드 요청에는 컬렉션 수준의 벡터 필드, EmbeddingList 요청 또는 서로 다른 StructArray 필드 아래의 요소 수준 요청이 포함됩니다. |
| 요소 수준 | 기본 키와 상위 StructArray 필드, 그리고 요소 오프셋. | 선택된 요소 오프셋은 API 또는 SDK를 통해 노출될 때 반환될 수 있습니다. | 모든 AnnSearchRequest 객체는 요소 수준이며 동일한 StructArray 필드 아래에 있습니다. |
제한 사항
element_scope는 하이브리드 검색에서 엔티티 수준 후보로 축소되어야 하는 StructArray 요소 수준AnnSearchRequest객체에 대해서만 사용하십시오.EmbeddingList 요청, 컬렉션 수준 벡터 요청 또는 동일한 StructArray 요소 수준의 하이브리드 검색에는
element_scope를 사용하지 마십시오.sumtopk_sum축소 전략은 또는 과 같은 양의 상관 관계 지표를 필요로 합니다. 와 함께 사용해서는 안 됩니다.IPCOSINEL2topk_sum또한topk_avg는 양의topk값을 요구합니다. 다른 축소 전략에는topk가 포함되어서는 안 됩니다.EmbeddingList 수준 StructArray 요청은 범위 검색이나 그룹화를 지원하지 않습니다.
하이브리드 그룹화는 동일한 StructArray 요소 수준의 하이브리드 검색에 대해서만 지원되며, 기본 키에 의해서만 가능합니다.
범위 검색과 그룹화를 함께 사용해서는 안 됩니다.
흔히 저지르는 실수
동일 StructArray 요소 수준 하이브리드 요청에
element_scope를 추가하는 경우. 해당 요청은 요소 수준으로 유지되며 엔티티 수준 접기는 수행되지 않습니다.chunks[emb_list_vector]에element_scope를 추가하는 경우. EmbeddingList 검색은 이미 엔티티 수준입니다.두 StructArray 필드가 요소 오프셋을 공유한다고 가정하는 경우.
chunks의 오프셋3과 다른 StructArray 필드의 오프셋3은 서로 다른 요소이므로, 하이브리드 요청은 엔티티 수준이 됩니다.topk_sum을L2과 함께 사용합니다. 음수 거리 메트릭의 경우max,avg또는topk_avg을 사용하십시오.축약 후 엔티티 수준 하이브리드 결과에 선택된 Struct 요소 오프셋이 포함될 것으로 예상됩니다.
다음 단계
두 가지 기본 StructArray 벡터 검색 모드에 대해 알아보려면 ‘StructArray를 사용한 기본 벡터 검색’을 참조하십시오.
하이브리드 검색에 스칼라 필터를 추가하려면 ‘StructArray를 사용한 필터링 검색’을 참조하십시오.
하이브리드 검색에서 점수 또는 거리 경계를 사용하려면 StructArray를 사용한 범위 검색을 참조하십시오.
요소 수준 하이브리드 결과를 상위 엔티티별로 그룹화하려면 StructArray를 사용한 그룹화 검색을 참조하십시오.
StructArray 검색 제한 사항을 확인하려면 ‘StructArray 제한 사항’을 참조하십시오.