使用 StructArray 進行分組搜尋
請使用此頁面,根據父實體對 StructArray 的元素層級搜尋結果進行分組。當多個 Struct 元素符合查詢條件時,元素層級搜尋可能會從同一實體中返回多個搜尋結果。分組功能會將這些元素搜尋結果合併,使每個父實體最多只出現一次。
本頁面使用《建立 StructArray 欄位》中的tech_articles 集合。該集合包含一個名為chunks 的 StructArray 欄位。其中chunks[emb] 向量子欄位已針對元素層級搜尋進行索引,並採用標準向量度量標準。
分組機制如何套用至 StructArray
| 搜尋模式 | 分組行為 | 結果行為 |
|---|---|---|
| EmbeddingList 搜尋 | 不支援。 | 不適用。 |
| 元素層級搜尋 | 透過主鍵分組可支援此功能。 | 每個父實體最多返回一個結果。元素層級的元資料會被保留,因此當 API 或 SDK 公開時,可返回所選元素的索引或偏移量。 |
| 混合搜尋 | 僅在所有子搜尋皆針對同一 StructArray 欄位下的元素層級向量欄位時才受支援。 | 在處理最終結果之前,元素層級的子搜尋會依據主鍵進行分組。 |
當未分組的元素層級搜尋會返回過多重複的父實體時,請使用分組功能。若您希望將每個符合條件的 Struct 元素視為獨立的搜尋結果,請使用不帶 `group_by_field`的 StructArray 基本向量搜尋。
開始之前
在執行分組搜尋之前,請先準備好集合、資料和索引。
| 需求 | 詳細資訊 |
|---|---|
| 元素層級向量子欄位 | 請使用 StructArray 向量子欄位(例如chunks[emb] ),並以常規向量度量作為索引。 |
| 常規向量查詢 | 請使用一般查詢向量,而非EmbeddingList 。 |
| 主鍵分組 | 請將集合主鍵設定為 `group_by_field`,例如 `doc_id`。 |
| 不使用範圍參數 | 請勿將分組搜尋與範圍搜尋參數(例如radius 或range_filter )結合使用。 |
有關索引設定,請參閱「Index 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 元素在回傳時的零起始位置。 |
| 重複的主鍵 | 按主鍵分組時不應出現此情況。 |
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 限制》。