使用 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 欄位 | 該集合包含一個 StructArray 欄位,例如chunks 。 |
| 向量子欄位 | 請分別使用獨立的向量子欄位來執行 EmbeddingList 搜尋與元素層級搜尋。 |
| 索引 | chunks[emb_list_vector] 使用MAX_SIM* 指標。chunks[emb] 則使用常規向量指標,例如COSINE 、IP 或L2 。 |
| 重新排序器 | 請選擇混合型重新排序器,例如RRFRanker 或您應用程式所支援的其他重新排序器。 |
有關索引設定,請參閱《Index 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 物件均產生實體層級的候選結果。最終結果以父實體的主鍵作為索引。請勿將 `element_scope ` 加入 EmbeddingList 請求中。
執行同 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 下搜尋向量子欄位。由於相同的以零為起點的偏移量指向同一個 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] 返回元素命中結果,接著透過將來自同一實體的返回元素中最佳的三個元素分數相加,來彙總這些元素。若在需要實體層級彙總時省略element_scope ,彙總策略將預設為max 。
選擇彙總策略
| 策略 | 行為 | topk | 指標要求 |
|---|---|---|---|
max | 保留該實體所返回的最佳元素分數。 | 不允許。 | 任何受支援的常規向量指標。 |
sum | 將該實體所有回傳元素的分數相加。 | 不允許。 | 僅限正相關指標,例如IP 或COSINE 。 |
avg | 將該實體所有回傳元素的評分求平均值。 | 不允許。 | 任何受支援的常規向量指標。 |
topk_sum | 將該實體所返回的元素中最佳的K 分數相加。 | 此為必填項目,且數值必須為正數。 | 僅限正相關指標,例如IP 或COSINE 。 |
topk_avg | 對該實體所返回的最佳K 元素分數求平均值。 | 此參數為必填且必須為正數。 | 任何受支援的常規向量指標。 |
Collapse 僅使用該 StructArray 元素級別AnnSearchRequest 所返回的元素命中結果。它在 ANN 搜尋後不會掃描實體中的每個 Struct 元素。請將請求的limit 設定得足夠高,以提供您希望用於 Collapse 的元素。
新增篩選器、範圍搜尋與分組
當標量條件需套用至參與向量搜尋的相同 Struct 元素時,可將element_filter 附加至 StructArray 元素層級的AnnSearchRequest 。您亦可針對父實體條件,在hybrid_search() 上使用頂層的filter 。
StructArray 元素層級向量欄位在混合搜尋中支援範圍搜尋。請將radius 以及(若需)range_filter 新增至元素層級的AnnSearchRequest 中。EmbeddingList 層級的 StructArray 請求不支援範圍搜尋。
僅當所有 `AnnSearchRequest ` 物件皆針對同一 `StructArray` 欄位下的元素層級向量欄位,且 `group_by_field ` 必須為主鍵時,才支援元素層級的混合分組。若請求混合了集合層級的向量欄位、不同的 `StructArray` 欄位,或 `EmbeddingList` 層級的請求,則不支援混合分組。請勿將範圍搜尋與分組結合使用。
解讀混合結果
| 最終候選範圍 | 結果鍵 | 偏移量行為 | 發生時 |
|---|---|---|---|
| 實體層級 | 主鍵。 | 最終結果中不包含元素偏移量。 | 混合請求包含集合層級的向量欄位、EmbeddingList 請求,或位於不同 StructArray 欄位下的元素層級請求。 |
| 元素層級 | 主鍵加上父級 StructArray 欄位,再加上元素偏移量。 | 當 API 或 SDK 公開時,可返回所選元素的偏移量。 | 所有 `AnnSearchRequest ` 物件均為元素層級,且位於同一個 `StructArray` 欄位之下。 |
限制
請僅將 `
element_scope` 用於 StructArray 元素層級的 `AnnSearchRequest` 物件,這些物件在混合搜尋中必須摺疊為實體層級的候選項目。請勿將
element_scope用於 EmbeddingList 請求、集合層級向量請求,或同一 StructArray 元素層級的混合搜尋。sum以及topk_sum收斂策略均需正相關指標,例如IP或COSINE。請勿將其與L2搭配使用。topk_sum且topk_avg需要正的topk值。其他彙總策略不得包含topk。嵌入式清單層級的 StructArray 請求不支援範圍搜尋或分組。
混合分組僅支援相同 StructArray 元素層級的混合搜尋,且僅限透過主鍵進行。
請勿將範圍搜尋與分組操作結合使用。
常見錯誤
在同一 StructArray 元素層級的混合請求中加入
element_scope。該請求仍維持在元素層級,且不會執行實體層級的彙總。將 `
element_scope` 新增至 `chunks[emb_list_vector]`。`EmbeddingList` 搜尋本身已是實體層級的。假設兩個 StructArray 欄位共享元素偏移量。
chunks中的偏移量3與另一個 StructArray 欄位中的偏移量3對應不同的元素,因此混合請求將轉為實體層級。若使用
topk_sum搭配L2,請使用max、avg或topk_avg來處理負數距離度量值。預期實體層級的混合結果在摺疊後將包含所選的 Struct 元素偏移量。
後續步驟
若要了解兩種基本的 StructArray 向量搜尋模式,請參閱《使用 StructArray 進行基本向量搜尋》。
若要將標量篩選器新增至混合搜尋,請參閱《使用 StructArray 進行篩選搜尋》。
若要在混合搜尋中使用分數或距離範圍,請參閱《使用 StructArray 進行範圍搜尋》。
若要依父實體將元素層級的混合搜尋結果分組,請參閱《使用 StructArray 進行分組搜尋》。
若要查看 StructArray 的搜尋限制,請參閱《StructArray 限制》。