範圍搜尋
範圍搜尋可將返回實體的距離或分數限制在特定範圍內,從而改善搜尋結果的相關性。本頁可協助您瞭解何謂範圍搜尋,以及執行範圍搜尋的程序。
概述
當執行範圍搜尋請求時,Milvus 以 ANN 搜尋結果中與查詢向量最相似的向量為中心,以搜尋請求中指定的半徑為外圈半徑,以range_filter為內圈半徑,畫出兩個同心圓。所有相似度分數落在這兩個同心圓所形成的環狀區域內的向量都會被傳回。在這裡,range_filter可以設定為0,表示將傳送指定相似度得分(半徑)範圍內的所有實體。
範圍搜尋
上圖顯示範圍搜尋請求包含兩個參數:半徑和range_filter。收到範圍搜尋請求後,Milvus 會執行下列動作。
使用指定的度量類型(COSINE) 來尋找與查詢向量最相似的所有向量內嵌。
篩選與查詢向量的距離或分數在半徑和range_filter參數指定範圍內的向量內嵌。
從篩選出的實體中傳回前 K個實體。
設定 radius 和range_filter的方式會因搜尋的度量類型而異。下表列出了在不同公制類型下設定這兩個參數的要求。
公制類型 | 符號 | 設定 radius 和 range_filter 的要求 |
---|---|---|
| L2 距離越小,表示相似度越高。 | 若要忽略最相似的向量嵌入,請確保
|
| IP 距離越大,表示相似度越高。 | 若要忽略最相似的向量嵌入,請確保
|
| COSINE 距離越大,表示相似度越高。 | 若要忽略最相似的向量嵌入,請確保
|
| 較小的 Jaccard 距離表示相似度較高。 | 若要忽略最相似的向量內嵌,請確保
|
| Hamming 距離越小,表示相似度越高。 | 若要忽略最相似的向量內嵌,請確保
|
範例
本節示範如何進行範圍搜尋。以下程式碼片段中的搜尋請求並不包含度量類型,這表示預設的度量類型COSINE適用。在這種情況下,請確保半徑值小於range_filter值。
在下列程式碼片段中,請將radius
設定為0.4
,並將range_filter
設定為0.6
,以便 Milvus 會傳回所有與查詢向量的距離或分數在0.4至0.6 之間的實體。
from pymilvus import MilvusClient
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="my_collection",
data=[query_vector],
limit=3,
search_params={
# highlight-start
"params": {
"radius": 0.4,
"range_filter": 0.6
}
# highlight-end
}
)
for hits in res:
print("TopK results:")
for hit in hits:
print(hit)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.token("root:Milvus")
.build());
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
Map<String,Object> extraParams = new HashMap<>();
extraParams.put("radius", 0.4);
extraParams.put("range_filter", 0.6);
SearchReq searchReq = SearchReq.builder()
.collectionName("range_search_collection")
.data(Collections.singletonList(queryVector))
.topK(5)
.searchParams(extraParams)
.build();
SearchResp searchResp = client.search(searchReq);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output
// TopK results:
// SearchResp.SearchResult(entity={}, score=0.5975797, id=4)
// SearchResp.SearchResult(entity={}, score=0.46704385, id=5)
// TODO
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});
var query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = await client.search({
collection_name: "range_search_collection",
data: [query_vector],
limit: 5,
// highlight-start
params: {
"radius": 0.4,
"range_filter": 0.6
}
// highlight-end
})
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"filter": "color like \"red%\" and likes > 50",
"limit": 3,
"searchParams": {
"params": {
"radius": 0.4,
"range_filter": 0.6
}
}
}'
# {"code":0,"cost":0,"data":[]}