StructArray를 사용한 검색 결과 그룹화
이 페이지를 사용하여 StructArray 요소 수준 검색 결과를 상위 엔티티별로 그룹화할 수 있습니다. 여러 Struct 요소가 쿼리와 일치할 경우, 요소 수준 검색에서는 동일한 엔티티에서 여러 개의 검색 결과가 반환될 수 있습니다. 그룹화 기능을 사용하면 이러한 요소 검색 결과를 통합하여 각 상위 엔티티가 최대 한 번만 표시되도록 합니다.
이 페이지에서는 ‘StructArray 필드 생성’의 tech_articles 컬렉션을 사용합니다. 이 컬렉션에는 chunks 라는 StructArray 필드가 있습니다. chunks[emb] 벡터 하위 필드는 일반 벡터 메트릭을 사용하여 요소 수준 검색이 가능하도록 인덱싱되어 있습니다.
StructArray에 그룹화가 적용되는 방식
| 검색 모드 | 그룹화 동작 | 결과 동작 |
|---|---|---|
| EmbeddingList 검색 | 지원되지 않음. | 해당 사항 없음. |
| 요소 수준 검색 | 기본 키를 기준으로 그룹화할 경우 지원됩니다. | 상위 엔티티당 최대 하나의 결과를 반환합니다. 요소 수준 메타데이터는 보존되므로, API 또는 SDK를 통해 노출될 때 선택된 요소 인덱스 또는 오프셋을 반환할 수 있습니다. |
| 하이브리드 검색 | 모든 하위 검색이 동일한 StructArray 필드 아래의 요소 수준 벡터 필드를 대상으로 하는 경우에만 지원됩니다. | 요소 수준 하위 검색은 최종 결과 처리 전에 기본 키를 기준으로 그룹화됩니다. |
그룹화되지 않은 요소 수준 검색에서 중복된 상위 엔티티가 너무 많이 반환되는 경우 그룹화를 사용하십시오. 일치하는 모든 Struct 요소를 개별 히트로 반환하려면 ` group_by_field`를 사용하지 않고 StructArray와 함께 기본 벡터 검색을 사용하십시오.
시작하기 전에
그룹화 검색을 실행하기 전에 컬렉션, 데이터 및 인덱스를 준비하십시오.
| 요구 사항 | 세부 정보 |
|---|---|
| 요소 수준 벡터 하위 필드 | chunks[emb] 와 같은 StructArray 벡터 하위 필드를 사용하고, 일반 벡터 메트릭으로 인덱싱하십시오. |
| 일반 벡터 쿼리 | EmbeddingList 가 아닌 일반 벡터 쿼리를 사용하십시오. |
| 기본 키 그룹화 | 컬렉션의 기본 키를 group_by_field 형태로 사용하십시오(예: doc_id). |
| 범위 매개변수 없음 | radius 또는 range_filter 와 같은 범위 검색 매개변수와 그룹화 검색을 함께 사용하지 마십시오. |
인덱스 설정에 대해서는 StructArray 필드 인덱스를 참조하십시오.
그룹화된 요소 수준 검색 실행
다음 예제는 먼저 개별 청크를 검색한 다음, 부모 엔티티의 기본 키를 기준으로 요소 검색 결과를 그룹화합니다.
from pymilvus import MilvusClient
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query_vector = [0.19, 0.24, 0.30, 0.37]
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
limit=5,
group_by_field="doc_id",
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[page]",
"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"],
)
그룹화를 하지 않으면, 여러 청크가 쿼리와 일치하는 경우 동일한 doc_id 가 여러 번 나타날 수 있습니다. group_by_field="doc_id" 를 사용하면 각 부모 엔티티가 최대 한 번만 나타납니다. 그룹화는 요소 수준 메타데이터를 보존하므로, API 또는 SDK가 이를 노출하는 경우 그룹화된 결과에도 선택한 Struct 요소 인덱스나 오프셋이 포함될 수 있습니다.
스칼라 필터 추가
그룹화 검색을 StructArray 스칼라 필터링과 결합할 수 있습니다. 스칼라 조건이 요소 수준 벡터 검색에 참여할 Struct 요소를 제한해야 할 때는 ` element_filter `를 사용하십시오.
filter_expr = (
'category == "search" && '
'element_filter(chunks, '
'$[section] == "index" && '
'$[quality_score] > 0.9)'
)
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
filter=filter_expr,
limit=5,
group_by_field="doc_id",
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
최상위 술어는 후보 엔티티를 선택합니다. ` element_filter ` 술어는 요소 수준 벡터 검색을 일치하는 Struct 요소로 제한합니다. 그런 다음 그룹화는 일차 키를 기준으로 일치하는 요소 검색 결과를 통합합니다.
하이브리드 검색에서 그룹화 사용
StructArray를 사용한 하이브리드 그룹화는 요소 수준 기능입니다. 이 기능은 모든 하위 검색이 동일한 StructArray 필드 하위의 요소 수준 벡터 필드를 대상으로 할 때만 지원됩니다. 그룹화된 StructArray 하이브리드 검색에서는 EmbeddingList 수준 요청을 사용하지 마십시오.
다음 예제는 chunks StructArray 필드에 chunks[emb] 및 chunks[code_emb] 라는 두 개의 요소 수준 벡터 하위 필드가 있으며, 둘 다 일반 벡터 메트릭으로 인덱싱되어 있다고 가정합니다.
from pymilvus import AnnSearchRequest, RRFRanker
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,
group_by_field="doc_id",
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
],
)
이 예제에서 두 하위 요청은 모두 동일한 StructArray 필드인 chunks 하위의 요소 수준 벡터 필드를 대상으로 합니다. 하이브리드 검색은 일반 벡터 필드, 서로 다른 StructArray 필드 또는 EmbeddingList 수준 요청이 혼합된 경우 요소 수준 그룹화를 지원하지 않습니다.
그룹화된 결과 해석
| 결과 항목 | 의미 |
|---|---|
id | 그룹화된 상위 엔터티의 기본 키입니다. |
distance 또는 점수 | 해당 상위 엔티티에 대해 선택된 Struct 요소의 점수 또는 거리. |
offset | 반환 시 선택된 Struct 요소의 0을 기준으로 한 위치. |
| 반복되는 기본 키 | 주키를 기준으로 그룹화할 때는 발생하지 않습니다. |
limit | 그룹화된 상위 엔티티 결과에 적용됩니다. |
제한 사항
그룹화 검색은 요소 수준의 StructArray 벡터 검색에만 적용됩니다. EmbeddingList 검색 및 EmbeddingList 수준의 하이브리드 검색은 그룹화 기능을 지원하지 않습니다.
주키를 `
group_by_field` 형식으로 사용하십시오. StructArray 요소 수준 그룹화는 임의의 스칼라 필드에 대한 범용 그룹화 기능이 아닙니다.그룹화 검색을 범위 검색과 결합하지 마십시오.
그룹화 검색에는 `
EmbeddingList` 쿼리나 `MAX_SIM*` 메트릭을 사용하지 마십시오.하이브리드 그룹화는 모든 하위 검색이 동일한 StructArray 필드 아래의 요소 수준 벡터 필드를 대상으로 하는 경우에만 지원됩니다.
하이브리드 검색이 일반 벡터 필드, 다른 StructArray 필드 또는 EmbeddingList 수준 요청을 혼합하는 경우 하이브리드 그룹화는 지원되지 않습니다.
흔히 저지르는 실수
chunks[emb_list_vector]와 함께 그룹화를 사용하는 경우. 이 기능은 EmbeddingList 검색용으로 설계되었습니다.주 키가 아닌 스칼라 필드를 기준으로 그룹화하는 경우.
여러 필드를 기준으로 그룹화하는 경우. 요소 수준 StructArray 그룹화는 기본 키 그룹화만 지원합니다.
그룹화된 결과가 일치하는 모든 Struct 요소를 나타낼 것이라고 기대하는 경우. 그룹화는 부모 엔티티당 최대 하나의 결과만 반환합니다.
그룹화된 요소 수준 검색이 EmbeddingList 스타일의
MAX_SIM*점수를 재계산한다고 가정하는 경우. 그룹화는 요소 수준 일치 결과를 통합할 뿐, 점수 산정 모델을 변경하지 않습니다.group_by_field를radius또는range_filter와 결합하는 경우.
다음 단계
먼저 그룹화되지 않은 요소 수준 검색에 대해 알아보려면 ‘StructArray를 사용한 기본 벡터 검색’을 참조하십시오.
그룹화된 검색에 스칼라 필터를 추가하려면 ‘StructArray를 사용한 필터링 검색’을 참조하십시오.
그룹화 대신 점수 또는 거리 경계를 사용하려면 StructArray를 사용한 범위 검색을 읽어보세요.
StructArray 검색 제한 사항을 확인하려면 ‘StructArray 제한 사항’을 참조하십시오.