使用 StructArray 進行基本向量搜尋
請使用此頁面對 StructArray 欄位內的向量子欄位執行向量搜尋。StructArray 支援兩種基本向量搜尋模式:嵌入清單搜尋(EmbeddingList search),此模式會對儲存於每個實體中的嵌入清單進行評分;以及元素層級搜尋,此模式會獨立搜尋每個 Struct 元素。
本頁面使用《建立 StructArray 欄位》中的tech_articles 集合。該集合包含一個名為chunks 的 StructArray 欄位。每個區塊包含文字、標量元數據、一個名為emb_list_vector 的向量子欄位(其索引用於 EmbeddingList 搜尋),以及一個名為emb 的向量子欄位(其索引用於元素層級搜尋)。
開始之前
請確保集合的架構、資料及索引均已準備就緒。
| 需求 | 準備位置 |
|---|---|
建立一個 StructArray 欄位,例如chunks 。 | 建立 StructArray 欄位 |
插入其 `chunks ` 欄位包含 Struct 物件的實體。 | 將資料插入 StructArray 欄位 |
在chunks[emb_list_vector] 上建立MAX_SIM* 索引,以便進行EmbeddingList搜尋。 | 為 StructArray 欄位建立索引 |
在 `chunks[emb] ` 上建立常規向量度量索引,以支援元素層級搜尋。 | 為 StructArray 欄位建立索引 |
警告
向量欄位或向量子欄位僅接受一個索引。若您同時需要 EmbeddingList 搜尋與元素層級搜尋,請建立兩個獨立的向量子欄位。在此頁面中,chunks[emb_list_vector] 已建立索引以供 EmbeddingList 搜尋使用,而chunks[emb] 則已建立索引以供元素層級搜尋使用。
選擇搜尋模式
| 方面 | EmbeddingList 搜尋 | 元素層級搜尋 |
|---|---|---|
| 目標子欄位 | chunks[emb_list_vector] | chunks[emb] |
| 查詢資料 | 一個包含一個或多個向量的嵌入清單。 | 一個常規向量。 |
| 度量族 | MAX_SIM*,例如MAX_SIM_COSINE 。 | 常規向量度量,例如COSINE 、IP 或L2 。 |
| 一個搜尋結果代表什麼 | 一個匹配的實體,其 StructArray 向量子欄位與查詢嵌入清單相似。 | StructArray 欄位內的匹配 Struct 元素。 |
| 結果的細粒度 | 實體層級。 | Struct 元素層級。 |
| 偏移量 | 不適用。 | 識別在返回時,匹配的結構體元素以零為起點的位置。 |
| 典型用途 | ColBERT、ColPali 及其他後期交互檢索模式。 | 塊級、段落級、片段級、區塊級或事實級檢索。 |
執行 EmbeddingList 搜尋
當查詢本身包含多個向量,且目標 StructArray 向量子欄位採用MAX_SIM* 度量進行索引時,請使用 EmbeddingList 搜尋。搜尋結果為實體層級的匹配。
from pymilvus import MilvusClient
from pymilvus.client.embedding_list import EmbeddingList
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query = EmbeddingList()
query.add([0.12, 0.21, 0.32, 0.44])
query.add([0.18, 0.23, 0.29, 0.36])
results = client.search(
collection_name="tech_articles",
data=[query],
anns_field="chunks[emb_list_vector]",
limit=3,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
],
)
for hits in results:
for hit in hits:
print(hit["id"], hit["distance"], hit["entity"])
在此搜尋模式下,limit 會控制每個查詢所返回的實體數量。輸出結果可能包含 StructArray 子欄位,但搜尋結果本身代表的是匹配的父實體,而非某個特定的 Struct 元素。
如需完整的 ColBERT 或 ColPali 風格操作指南,請參閱《使用嵌入式清單進行搜尋》。本頁面僅涵蓋 StructArray 的基本搜尋行為。
執行元素層級搜尋
當每個 Struct 元素應獨立參與向量搜尋時,請使用元素層級搜尋。查詢為一般向量,且目標向量子欄位必須採用一般向量度量進行索引。
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,
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"],
)
在元素層級搜尋中,每個搜尋結果代表一個匹配的 Struct 元素。offset 值即為該元素在 StructArray 欄位中的零起始位置。若有多個 Struct 元素與查詢相符,同一實體可能會出現多次。limit 值適用於元素搜尋結果,而非唯一的父實體。
解讀結果
| 結果項目 | EmbeddingList 搜尋 | 元素層級搜尋 |
|---|---|---|
id | 匹配實體的主鍵。 | 包含匹配 Struct 元素之實體的主鍵。 |
distance 或分數 | 查詢嵌入清單與儲存的嵌入清單之間的分數或距離。 | 查詢向量與匹配的 Struct 元素向量之間的分數或距離。 |
offset | 不適用。 | 回傳時,匹配 Struct 元素的從零開始的索引位置。 |
| 重複的主鍵 | 由於結果是實體層級的,因此單一查詢中不預期會出現此情況。 | 可能發生,因為同一實體中的多個 Struct 元素可能會匹配。 |
| 請求的 StructArray 輸出欄位 | 由匹配的實體返回。 | 將依照目標 API 和 SDK 所支援的元素層級命中結構進行回傳。 |
常見錯誤
使用 `
chunks.emb` 代替所需的子欄位路徑語法 `chunks[emb]`。對使用常規向量度量進行索引的向量子欄位,使用 EmbeddingList 查詢。
對使用
MAX_SIM*度量進行索引的向量子欄位,使用一般向量查詢。預期元素層級搜尋
limit會回傳相應數量的唯一父實體。其實它回傳的是元素匹配結果。預期 EmbeddingList 搜尋會返回一個特定的元素偏移量,但實際返回的是實體層級的匹配結果。
將同一個向量子欄位同時用於兩種搜尋模式。應使用獨立的向量子欄位,因為每個向量子欄位僅能接受一種索引。
後續步驟
若要透過標量條件限制元素層級搜尋,請參閱《使用 StructArray 進行篩選搜尋》。
若要根據分數或距離範圍進行搜尋,請參閱《使用 StructArray 進行範圍搜尋》。
若要在元素層級搜尋後,針對每個父實體最多返回一個結果,請參閱《使用 StructArray 進行分組搜尋》。
若要將 StructArray 搜尋與其他向量搜尋結合使用,請參閱《使用 StructArray 進行混合搜尋》。
若要檢視受支援的資料類型、度量、篩選器及特定版本的限制,請參閱《StructArray 限制》。