使用 StructArray 進行範圍搜尋
請使用此頁面對 StructArray 的向量子欄位執行範圍搜尋。範圍搜尋會回傳分數或距離落在指定範圍內的向量搜尋結果。對於 StructArray 欄位,請搭配元素層級的向量搜尋來執行範圍搜尋,此時每個 Struct 元素都會獨立進行搜尋。
本頁面使用《建立 StructArray 欄位》中的tech_articles 集合。該集合包含一個名為chunks 的 StructArray 欄位。其chunks[emb] 向量子欄位已建立索引,可透過標準向量度量(例如COSINE 、IP 或L2 )進行元素層級搜尋。
範圍搜尋如何套用至 StructArray
| 搜尋模式 | 範圍搜尋行為 | 結果粒度 |
|---|---|---|
| EmbeddingList 搜尋 | 不支援。 | 不適用。 |
| 元素層級搜尋 | 請使用帶有 `radius ` 的常規向量查詢,並可選擇性地使用 `range_filter`。 | 結構體元素層級。 |
| 混合搜尋 | 當 StructArray 請求針對元素層級向量欄位時,此功能受支援。EmbeddingList 層級的請求不支援範圍搜尋。 | 先進行元素層級子搜尋,再進行混合重新排序。 |
若您僅需最接近的 Struct 元素,請先使用 StructArray 進行基本向量搜尋。當結果必須滿足分數或距離邊界(而非僅限前 K 名排名)時,請使用範圍搜尋。
開始之前
執行範圍搜尋前,請先準備好集合、資料及索引。
| 需求 | 詳細資訊 |
|---|---|
| StructArray 欄位 | 該集合包含一個 StructArray 欄位,例如chunks 。 |
| 元素層級的向量子欄位 | 目標向量子欄位應為chunks[emb] ,而非chunks[emb_list_vector] 。 |
| 索引度量 | 該向量子欄位採用標準向量度量進行索引,例如COSINE 、IP 或L2 。 |
| 查詢資料 | 查詢為一般向量,而非EmbeddingList 。 |
有關索引設定,請參閱《索引 StructArray 欄位》。
使用 radius 和 range_filter
設定 `radius ` 以定義搜尋邊界。若同時需要內側邊界,請設定 `range_filter `。方向取決於「較小的距離」與「較高的相似度分數」何者更為理想。
| 度量類型 | 分數越高越好? | 使用 `range_filter ` 時的範圍條件 |
|---|---|---|
L2 | 否。距離越小越好。 | range_filter <= distance < radius |
IP,COSINE | 是。分數越高越好。 | radius < distance <= range_filter |
當僅設定 `radius ` 時,範圍搜尋會回傳符合該度量外界限的結果。請根據您的嵌入向量之分數或距離尺度來選擇數值。
執行元素層級範圍搜尋
以下範例會搜尋那些其 `chunks[emb] ` 向量與查詢向量足夠相似的個別片段。每個搜尋結果皆代表一個匹配的 Struct 元素。
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]",
search_params={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
limit=10,
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"],
)
在此範例中,COSINE 為相似度型指標,因此結果範圍大於radius 且小於或等於range_filter 。當結果返回時,offset 值會識別出chunks 陣列中匹配的 Struct 元素。
新增標量篩選條件
您可以將元素層級的範圍搜尋與 StructArray 標量篩選結合使用。針對父實體欄位使用頂層謂詞,並使用element_filter 來限制哪些 Struct 元素會參與向量範圍搜尋。
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]",
search_params={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
filter=filter_expr,
limit=10,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
頂層謂詞用於篩選候選實體。element_filter 謂詞則將向量範圍搜尋限制在符合條件的 Struct 元素上。如需更多篩選範例,請參閱《使用 StructArray 進行篩選搜尋》。
在混合搜尋中使用範圍搜尋
StructArray 元素層級向量欄位在混合搜尋中支援範圍搜尋。請將 `radius ` 以及(若需)`range_filter ` 新增至針對 StructArray 元素層級向量欄位的 `AnnSearchRequest ` 中。
from pymilvus import AnnSearchRequest, RRFRanker
title_req = AnnSearchRequest(
data=[query_vector],
anns_field="title_vector",
limit=10,
)
chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
param={
"params": {
"radius": 0.80,
"range_filter": 0.95,
},
},
limit=10,
expr='element_filter(chunks, $[section] == "index")',
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[title_req, chunk_req],
ranker=RRFRanker(),
limit=5,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
在此範例中,僅有 `chunks[emb] ` 子請求會使用範圍搜尋參數。StructArray 請求仍遵循元素層級語義:範圍邊界適用於混合搜尋合併並重新排序結果之前所找到的 Struct 元素命中項目。
解析範圍結果
| 結果項目 | 含義 |
|---|---|
id | 包含匹配 Struct 元素之實體的主鍵。 |
distance 或分數 | 查詢向量與匹配的 Struct 元素向量之間的分數或距離。 |
offset | 回傳時,匹配的 Struct 元素在 StructArray 欄位中的零起始位置。 |
| 重複的主鍵 | 可能發生。同一實體中可能有超過一個 Struct 元素落在指定範圍內。 |
limit | 此規則適用於元素命中,而非唯一的父實體。 |
限制
請勿對 StructArray 向量子欄位使用
EmbeddingList查詢或MAX_SIM*指標進行範圍搜尋。EmbeddingList 層級的搜尋不支援範圍搜尋。請勿將範圍搜尋與分組搜尋結合使用。若需針對每個父實體返回一個結果,請執行不包含範圍參數的元素層級搜尋,並在支援的情況下使用分組功能。
StructArray 元素層級的向量欄位支援混合範圍搜尋。但 EmbeddingList 層級的 StructArray 請求則不支援此功能。
常見錯誤
針對
chunks[emb_list_vector]執行範圍搜尋,該指標原本是為 EmbeddingList 搜尋設計的。在元素層級範圍搜尋中,使用 `
MAX_SIM_COSINE` 取代常規指標(例如 `COSINE`)。使用
EmbeddingList查詢,而非一般向量查詢。預期範圍搜尋結果在父實體層級下是唯一的。範圍搜尋會返回符合條件的 Struct 元素命中結果。
使用 `
chunks.emb` 取代必需的子欄位路徑語法 `chunks[emb]`。
後續步驟
若要了解 StructArray 的兩種基本向量搜尋模式,請參閱《使用 StructArray 進行基本向量搜尋》。
若要為範圍搜尋新增標量篩選條件,請參閱《使用 StructArray 進行篩選搜尋》。
若要在支援的情況下,針對每個父實體最多返回一個結果,請參閱《使用 StructArray 進行分組搜尋》。
若要查看特定版本的搜尋限制,請參閱《StructArray 限制》。