在 Azure AI 搜尋服務的向量查詢中新增篩選
您可以定義包含篩選運算式的向量查詢要求,以將包含或排除準則新增至查詢。 在本文中,了解如何:
本文使用 REST 進行說明。 如需其他語言的程式碼范例,請參閱 azure-search-vector-samples GitHub 存放庫,了解包括向量査詢的端對端解決方案。
您也可以在 Azure 入口網站中使用搜尋總管來查詢向量內容。 如果使用 JSON 檢視,您可以新增篩選並指定篩選模式。
篩選在向量查詢中的運作方式
篩選適用於 filterable
非向量欄位 (字串欄位或數值),以根據篩選準則包括或排除搜尋文件。 儘管向量欄位本身不可篩選,但篩選可套用至同一索引中的其他欄位,包括或排除也包含向量欄位的文件。
篩選會根據 vectorFilterMode
參數在查詢執行之前或之後套用。
定義篩選器
篩選會決定向量查詢的範圍。 篩選會在索引中屬性為 filterable
的非向量字串和數值欄位上設定並逐一查看,但篩選的目的會決定向量查詢執行所在的「目標」:整個可搜尋的空間,或是某個搜尋結果的內容。
如果您沒有搭配文字或數值的來源欄位,請檢查可能在中繼資料篩選條件中很有用的文件中繼資料,例如 LastModified 或 CreatedBy 屬性。
2024-07-01 是此 API 的穩定版本。 其中包含:
- 適用於預先篩選 (預設) 或後置篩選的
vectorFilterMode
篩選結果。 filter
會提供準則。
在下列範例中,向量是此查詢字串的表示法:「哪些 Azure 服務支援全文檢索搜尋」。 査詢以 contentVector
欄位為目標。 實際向量有 1536 個內嵌,因此為了可讀性會在此範例中修剪此向量。
在搜尋引擎執行向量查詢之前,篩選準則會套用至可篩選的文字欄位 (此範例中的 category
)。
POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-07-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
"count": true,
"select": "title, content, category",
"filter": "category eq 'Databases'",
"vectorFilterMode": "preFilter",
"vectorQueries": [
{
"kind": "vector",
"vector": [
-0.009154141,
0.018708462,
. . .
-0.02178128,
-0.00086512347
],
"exhaustive": true,
"fields": "contentVector",
"k": 5
}
]
}
設定 vectorFilterMode
vectorFilterMode 查詢參數會決定篩選是要在向量查詢執行之前還是之後套用。
使用預先篩選模式
預先篩選會在查詢執行之前套用篩選,進而減少向量搜尋演算法尋找類似內容的搜尋介面區。
在向量查詢中,preFilter
是預設值。
使用後置篩選模式
後置篩選會在查詢執行之後套用篩選,進而縮小搜尋結果。
向量篩選模式的基準測試
為了了解這些篩選模式在各種環境中的效能差異,我們執行了一系列測試,以評估其針對小型、中型和大型索引的查詢結果。
- 小型 (100,000 份文件、2.5 GB 索引、1536 個維度)
- 中型 (1 百萬份文件、25 GB 索引、1536 個維度)
- 大型 (10 億份文件、1.9 TB 索引、96 個維度)
針對小型和中型工作負載,我們使用標準 2 (S2) 服務搭配一個分割區和一個複本。 針對大型工作負載,我們使用標準 3 (S3) 服務搭配 12 個分割區和一個複本。
索引具有相同的建構:一個索引欄位、一個向量欄位、一個文字欄位,以及一個數值可篩選欄位。 下列索引是使用 2023-11-03 語法來定義。
def get_index_schema(self, index_name, dimensions):
return {
"name": index_name,
"fields": [
{"name": "id", "type": "Edm.String", "key": True, "searchable": True},
{"name": "content_vector", "type": "Collection(Edm.Single)", "dimensions": dimensions,
"searchable": True, "retrievable": True, "filterable": False, "facetable": False, "sortable": False,
"vectorSearchProfile": "defaulthnsw"},
{"name": "text", "type": "Edm.String", "searchable": True, "filterable": False, "retrievable": True,
"sortable": False, "facetable": False},
{"name": "score", "type": "Edm.Double", "searchable": False, "filterable": True,
"retrievable": True, "sortable": True, "facetable": True}
],
"vectorSearch": {
"algorithms": [
{
"name": "defaulthnsw",
"kind": "hnsw",
"hnswParameters": { "metric": "euclidean" }
}
],
"profiles": [
{
"name": "defaulthnsw",
"algorithm": "defaulthnsw"
}
]
}
}
在查詢中,我們針對預先篩選和後置篩選作業使用相同的篩選。 我們使用簡單的篩選來確保效能的變化是源自於篩選模式的不同,而不是篩選複雜度。
結果是以每秒查詢次數 (QPS) 來測量。
重要心得
預先篩選幾乎一律比後置篩選還要慢,但針對小型索引除外,在該情況下兩種篩選的效能大致相等。
針對較大的資料集,預先篩選的速度慢上非常多。
那麼,如果預先篩選幾乎總是比較慢,為什麼會將其作為預設值? 預先篩選能確保系統會在
k
個結果存在於索引的情況下將其傳回,其中偏差會偏向重新叫用和精確度,而非速度。後置篩選適用於下列客戶:
- 重視速度大於選取項目 (後置篩選可能會傳回少於
k
個結果) - 使用不具過度選擇性的篩選
- 索引的大小大到無法接受預先篩選的效能
- 重視速度大於選取項目 (後置篩選可能會傳回少於
詳細資料
以位於 1536 個維度之 100,000 個向量的資料集為例:
- 篩選超過 30% 的資料集時,預先篩選和後置篩選的速度是相當的。
- 篩選少於 0.1% 的資料集時,預先篩選的速度會比後置篩選慢 50%。
以位於 1536 個維度之 1 百萬個向量的資料集為例:
- 篩選多於 30% 的資料集時,預先篩選的速度會慢 30%。
- 篩選少於 2% 的資料集時,預先篩選的速度會慢七倍。
以位於 96 個維度之 10 億個向量的資料集為例:
- 篩選多於 5% 的資料集時,預先篩選的速度會慢 50%。
- 篩選少於 10% 的資料集時,預先篩選的速度會慢七倍。
下圖顯示預先篩選相對 QPS,其是以預先篩選 QPS 除以後置篩選 QPS 來計算。
垂直軸是預先篩選的 QPS 除以後置篩選的 QPS。 例如,0.0 的值表示預先篩選的速度慢 100%,垂直軸上的 0.5 表示預先篩選的速度慢 50%,1.0 表示預先篩選和後置篩選的速度相當。
水平軸代表篩選速率,也就是套用篩選後的候選文件百分比。 例如,1.00%
表示篩選準則選取搜尋主體的百分之一。