使用 StructArray 進行範圍搜尋

請使用此頁面對 StructArray 的向量子欄位執行範圍搜尋。範圍搜尋會回傳分數或距離落在指定範圍內的向量搜尋結果。對於 StructArray 欄位,請搭配元素層級的向量搜尋來執行範圍搜尋,此時每個 Struct 元素都會獨立進行搜尋。

本頁面使用《建立 StructArray 欄位》中的tech_articles 集合。該集合包含一個名為chunks 的 StructArray 欄位。其chunks[emb] 向量子欄位已建立索引,可透過標準向量度量(例如COSINEIPL2 )進行元素層級搜尋。

範圍搜尋如何套用至 StructArray

搜尋模式範圍搜尋行為結果粒度
EmbeddingList 搜尋不支援。不適用。
元素層級搜尋請使用帶有 `radius ` 的常規向量查詢,並可選擇性地使用 `range_filter`。結構體元素層級。
混合搜尋當 StructArray 請求針對元素層級向量欄位時,此功能受支援。EmbeddingList 層級的請求不支援範圍搜尋。先進行元素層級子搜尋,再進行混合重新排序。

若您僅需最接近的 Struct 元素,請先使用 StructArray 進行基本向量搜尋。當結果必須滿足分數或距離邊界(而非僅限前 K 名排名)時,請使用範圍搜尋。

開始之前

執行範圍搜尋前,請先準備好集合、資料及索引。

需求詳細資訊
StructArray 欄位該集合包含一個 StructArray 欄位,例如chunks
元素層級的向量子欄位目標向量子欄位應為chunks[emb] ,而非chunks[emb_list_vector]
索引度量該向量子欄位採用標準向量度量進行索引,例如COSINEIPL2
查詢資料查詢為一般向量,而非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]`。

後續步驟

  1. 若要了解 StructArray 的兩種基本向量搜尋模式,請參閱《使用 StructArray 進行基本向量搜尋》。

  2. 若要為範圍搜尋新增標量篩選條件,請參閱《使用 StructArray 進行篩選搜尋》。

  3. 若要在支援的情況下,針對每個父實體最多返回一個結果,請參閱《使用 StructArray 進行分組搜尋》。

  4. 若要查看特定版本的搜尋限制,請參閱《StructArray 限制》。