基本向量搜尋
Approximate Nearest Neighbor (ANN) 搜尋是以記錄向量內嵌排序順序的索引檔案為基礎,根據接收到的搜尋請求中的查詢向量,找出向量內嵌的子集,將查詢向量與子集中的向量進行比較,並返回最相似的結果。透過 ANN 搜尋,Milvus 提供了高效率的搜尋體驗。本頁可協助您學習如何進行基本的 ANN 搜尋。
如果您在集合建立後動態新增欄位,包含這些欄位的搜尋將回傳定義的預設值,或對於沒有明確設定值的實體回傳 NULL。如需詳細資訊,請參閱新增欄位到現有的集合。
概觀
ANN 和 k-Nearest Neighbors (kNN) 搜尋是向量相似性搜尋的常用方法。在 kNN 搜尋中,您必須將向量空間中的所有向量與搜尋請求中的查詢向量進行比較,才能找出最相似的向量,這既耗時又耗資。
與 kNN 搜尋不同,ANN 搜尋演算法要求一個索引檔案,記錄向量嵌入的排序順序。當收到搜尋要求時,您可以使用索引檔案作為參考,快速找出可能包含與查詢向量最相似的向量內嵌的子群。然後,您可以使用指定的度量類型來測量查詢向量與子群組中的向量之間的相似度,根據與查詢向量的相似度來排序群組成員,並找出前 K 個群組成員。
ANN 搜尋依賴預先建立的索引,搜尋的吞吐量、記憶體使用量和搜尋正確性可能會隨您選擇的索引類型而有所不同。您需要平衡搜尋效能與正確性。
為了降低學習曲線,Milvus 提供AUTOINDEX。有了AUTOINDEX,Milvus 可以在建立索引的同時,分析您的資料集中的資料分佈,並根據分析結果設定最優化的索引參數,在搜尋效能和正確性之間取得平衡。
在本節中,您可以找到以下主題的詳細資訊:
單向量搜尋
在 ANN 搜尋中,單向量搜尋指的是只涉及一個查詢向量的搜尋。根據預先建立的索引和搜尋請求所帶的度量類型,Milvus 會找出與查詢向量最相似的前 K 個向量。
在本節中,您將學習如何進行單一向量搜尋。搜尋請求會攜帶一個單一的查詢向量,並要求 Milvus 使用 Inner Product (IP) 來計算查詢向量與集合中向量的相似度,並傳回三個最相似的向量。
from pymilvus import MilvusClient
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="quick_setup",
anns_field="vector",
data=[query_vector],
limit=3,
search_params={"metric_type": "IP"}
)
for hits in res:
for hit in hits:
print(hit)
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
import java.util.*;
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});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(Collections.singletonList(queryVector))
.annsField("vector")
.topK(3)
.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.95944905, id=5)
// SearchResp.SearchResult(entity={}, score=0.8689616, id=1)
// SearchResp.SearchResult(entity={}, score=0.866088, id=7)
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v2/entity"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
milvusAddr := "localhost:19530"
token := "root:Milvus"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: milvusAddr,
APIKey: token,
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
defer client.Close(ctx)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithANNSField("vector"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});
// 4. Single vector search
var query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = await client.search({
collection_name: "quick_setup",
data: query_vector,
limit: 3, // The number of results to return
})
console.log(res.results)
// [
// { score: 0.08821295201778412, id: '551' },
// { score: 0.0800950899720192, id: '296' },
// { score: 0.07794742286205292, id: '43' }
// ]
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" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3
}'
# {
# "code": 0,
# "data": [
# {
# "distance": 0.08821295201778412,
# "id": 551
# },
# {
# "distance": 0.0800950899720192,
# "id": 296
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# }
# ]
# }
Milvus 依據搜尋結果與查詢向量的相似度得分,以降序排列搜尋結果。相似性分數也稱為與查詢向量的距離,其值範圍會因使用的度量類型而異。
下表列出了適用的度量類型和相對應的距離範圍。
度量類型 |
特性 |
距離範圍 |
|---|---|---|
|
較小的值表示較高的相似性。 |
[0, ∞) |
|
值越大表示相似度越高。 |
[-1, 1] |
|
較大的值表示較高的相似性。 |
[-1, 1] |
|
值越小,表示相似度越高。 |
[0, 1] |
|
較小的值表示較高的相似度。 |
[0,dim(向量)] |
大量向量搜尋
同樣地,您可以在一個搜尋請求中包含多個查詢向量。Milvus 會平行地對查詢向量進行 ANN 搜尋,並傳回兩組結果。
# 7. Search with multiple vectors
# 7.1. Prepare query vectors
query_vectors = [
[0.041732933, 0.013779674, -0.027564144, -0.013061441, 0.009748648],
[0.0039737443, 0.003020432, -0.0006188639, 0.03913546, -0.00089768134]
]
# 7.2. Start search
res = client.search(
collection_name="quick_setup",
data=query_vectors,
limit=3,
)
for hits in res:
print("TopK results:")
for hit in hits:
print(hit)
# Output
#
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ],
# [
# {
# "id": 730,
# "distance": 0.04431751370429993,
# "entity": {}
# },
# {
# "id": 333,
# "distance": 0.04231833666563034,
# "entity": {}
# },
# {
# "id": 232,
# "distance": 0.04221535101532936,
# "entity": {}
# }
# ]
# ]
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.BaseVector;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
List<BaseVector> queryVectors = Arrays.asList(
new FloatVec(new float[]{0.041732933f, 0.013779674f, -0.027564144f, -0.013061441f, 0.009748648f}),
new FloatVec(new float[]{0.0039737443f, 0.003020432f, -0.0006188639f, 0.03913546f, -0.00089768134f})
);
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(queryVectors)
.topK(3)
.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.49548206, id=1)
// SearchResp.SearchResult(entity={}, score=0.320147, id=3)
// SearchResp.SearchResult(entity={}, score=0.107413776, id=6)
// TopK results:
// SearchResp.SearchResult(entity={}, score=0.5678123, id=6)
// SearchResp.SearchResult(entity={}, score=0.32368967, id=2)
// SearchResp.SearchResult(entity={}, score=0.24108477, id=3)
queryVectors := []entity.Vector{
entity.FloatVector([]float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}),
entity.FloatVector([]float32{0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104}),
}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
queryVectors,
).WithConsistencyLevel(entity.ClStrong).
WithANNSField("vector"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
// 7. Search with multiple vectors
const query_vectors = [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]
]
res = await client.search({
collection_name: "quick_setup",
vectors: query_vectors,
limit: 3,
})
console.log(res.results)
// Output
//
// [
// [
// { score: 0.08821295201778412, id: '551' },
// { score: 0.0800950899720192, id: '296' },
// { score: 0.07794742286205292, id: '43' }
// ],
// [
// { score: 0.04431751370429993, id: '730' },
// { score: 0.04231833666563034, id: '333' },
// { score: 0.04221535101532936, id: '232' },
// ]
// ]
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" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]
],
"annsField": "vector",
"limit": 3
}'
# {
# "code": 0,
# "data": [
# [
# {
# "distance": 0.08821295201778412,
# "id": 551
# },
# {
# "distance": 0.0800950899720192,
# "id": 296
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# }
# ],
# [
# {
# "distance": 0.04431751370429993,
# "id": 730
# },
# {
# "distance": 0.04231833666563034,
# "id": 333
# },
# {
# "distance": 0.04221535101532936,
# "id": 232
# }
# ]
# ],
# "topks":[3]
# }
主鍵搜尋Compatible with Milvus 2.6.9+
如果查詢向量已經存在於目標集合中,您可以使用主鍵來取代設定查詢向量。
res = client.search(
collection_name="quick_setup",
anns_field="vector",
ids=[551, 296, 43],
limit=3,
search_params={"metric_type": "IP"}
)
for hits in res:
for hit in hits:
print(hit)
// java
// node.js
// go
# restful
分區中的 ANN 搜尋
假設您在一個集合中建立了多個分割區,而且您可以將搜尋範圍縮小到特定數量的分割區。在這種情況下,您可以在搜尋請求中包含目標磁碟分割名稱,以將搜尋範圍限制在指定的磁碟分割內。減少搜尋所涉及的磁碟分割數目可改善搜尋效能。
以下程式碼片段假設您的集合中有一個名為PartitionA的分割區。
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
collection_name="quick_setup",
partition_names=["partitionA"],
data=[query_vector],
limit=3,
)
for hits in res:
print("TopK results:")
for hit in hits:
print(hit)
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {}
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {}
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {}
# }
# ]
# ]
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.partitionNames(Collections.singletonList("partitionA"))
.data(Collections.singletonList(queryVector))
.topK(3)
.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.6395302, id=13)
// SearchResp.SearchResult(entity={}, score=0.5408028, id=12)
// SearchResp.SearchResult(entity={}, score=0.49696884, id=17)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithConsistencyLevel(entity.ClStrong).
WithPartitions("partitionA").
WithANNSField("vector"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
// 4. Single vector search
var query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = await client.search({
collection_name: "quick_setup",
partition_names: ["partitionA"],
data: query_vector,
limit: 3, // The number of results to return
})
console.log(res.results)
// [
// { score: 0.08821295201778412, id: '551' },
// { score: 0.0800950899720192, id: '296' },
// { score: 0.07794742286205292, id: '43' }
// ]
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" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"partitionNames": ["partitionA"],
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3
}'
# {
# "code": 0,
# "data": [
# {
# "distance": 0.08821295201778412,
# "id": 551
# },
# {
# "distance": 0.0800950899720192,
# "id": 296
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# }
# ],
# "topks":[3]
# }
使用輸出欄位
在搜尋結果中,Milvus 預設會包含包含 top-K 向量嵌入的實體的主要欄位值和相似性距離/分數。您可以在搜尋請求中包含目標欄位的名稱,包括向量和標量欄位,作為輸出欄位,讓搜尋結果帶有這些實體中其他欄位的值。
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={"metric_type": "IP"},
output_fields=["color"]
)
print(res)
# [
# [
# {
# "id": 551,
# "distance": 0.08821295201778412,
# "entity": {
# "color": "orange_6781"
# }
# },
# {
# "id": 296,
# "distance": 0.0800950899720192,
# "entity": {
# "color": "red_4794"
# }
# },
# {
# "id": 43,
# "distance": 0.07794742286205292,
# "entity": {
# "color": "grey_8510"
# }
# }
# ]
# ]
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(Collections.singletonList(queryVector))
.topK(3)
.outputFields(Collections.singletonList("color"))
.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={color=black_9955}, score=0.95944905, id=5)
// SearchResp.SearchResult(entity={color=red_7319}, score=0.8689616, id=1)
// SearchResp.SearchResult(entity={color=white_5015}, score=0.866088, id=7)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithConsistencyLevel(entity.ClStrong).
WithANNSField("vector").
WithOutputFields("color"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
fmt.Println("color: ", resultSet.GetColumn("color").FieldData().GetScalars())
}
// 4. Single vector search
var query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = await client.search({
collection_name: "quick_setup",
data: query_vector,
limit: 3, // The number of results to return
output_fields: ["color"]
})
console.log(res.results)
// [
// { score: 0.08821295201778412, id: '551', entity: {"color": "orange_6781"}},
// { score: 0.0800950899720192, id: '296' entity: {"color": "red_4794"}},
// { score: 0.07794742286205292, id: '43' entity: {"color": "grey_8510"}}
// ]
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" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3,
"outputFields": ["color"]
}'
# {
# "code": 0,
# "data": [
# {
# "distance": 0.08821295201778412,
# "id": 551,
# "color": "orange_6781"
# },
# {
# "distance": 0.0800950899720192,
# "id": 296,
# "color": "red_4794"
# },
# {
# "distance": 0.07794742286205292,
# "id": 43
# "color": "grey_8510"
# }
# ],
# "topks":[3]
# }
使用限制和偏移
您可能會注意到,搜尋要求中攜帶的參數limit 會決定搜尋結果中包含的實體數目。此參數指定在單次搜尋中返回的最大實體數目,通常稱為top-K。
如果您希望執行分頁查詢,可以使用循環傳送多個 Search 請求,並在每個查詢請求中載入Limit和Offset參數。具體來說,您可以將Limit參數設定為您想要包含在目前查詢結果中的 Entities 數量,並將Offset設定為已經返回的 Entities 總數。
下表概述了在一次返回 100 個實體時,如何為分頁查詢設定Limit和Offset參數。
查詢 |
每次查詢要返回的實體 |
已返回的實體總數 |
|---|---|---|
第 1 次查詢 |
100 |
0 |
第二次查詢 |
100 |
100 |
第三次查詢 |
100 |
200 |
第 n 次查詢 |
100 |
100 x (n-1) |
請注意,在單一 ANN 搜尋中,limit 和offset 的總和應該小於 16,384。
# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = client.search(
collection_name="quick_setup",
data=[query_vector],
limit=3, # The number of results to return
search_params={
"metric_type": "IP",
"offset": 10 # The records to skip
}
)
import io.milvus.v2.service.vector.request.SearchReq
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp
FloatVec queryVector = new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f});
SearchReq searchReq = SearchReq.builder()
.collectionName("quick_setup")
.data(Collections.singletonList(queryVector))
.topK(3)
.offset(10)
.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.24120237, id=16)
// SearchResp.SearchResult(entity={}, score=0.22559784, id=9)
// SearchResp.SearchResult(entity={}, score=-0.09906838, id=2)
queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"quick_setup", // collectionName
3, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithConsistencyLevel(entity.ClStrong).
WithANNSField("vector").
WithOffset(10))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
}
// 4. Single vector search
var query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592],
res = await client.search({
collection_name: "quick_setup",
data: query_vector,
limit: 3, // The number of results to return,
offset: 10 // The record to skip.
})
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" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "quick_setup",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 3,
"offset": 10
}'
為搜尋暫時設定時區
如果您的資料集中有TIMESTAMPTZ 欄位,您可以在搜尋呼叫中設定timezone 參數,以暫時覆寫資料庫或資料集中單次操作的預設時區。這可以控制TIMESTAMPTZ 值在操作過程中的顯示和比較方式。
timezone 的值必須是有效的IANA 時區識別碼(例如,亞洲/上海、美國/芝加哥或UTC)。有關如何使用TIMESTAMPTZ 欄位的詳細資訊,請參閱TIMESTAMPTZ 欄位。
以下範例說明如何為搜尋作業暫時設定時區:
res = client.search(
collection_name="quick_setup",
anns_field="vector",
data=[query_vector],
limit=3,
search_params={"metric_type": "IP"},
timezone="America/Havana",
)
// java
// js
// go
# restful
增強 ANN 搜尋
AUTOINDEX 可大幅拉平 ANN 搜尋的學習曲線。然而,隨著 top-K 的增加,搜尋結果不一定總是正確的。藉由縮小搜尋範圍、改善搜尋結果的相關性,以及使搜尋結果更多元化,Milvus 進行了以下的搜尋強化。
過濾搜尋
您可以在搜尋請求中加入過濾條件,讓 Milvus 在進行 ANN 搜尋之前先進行元資料過濾,將搜尋範圍從整個集合縮小到只有符合指定過濾條件的實體。
範圍搜尋
您可以在特定範圍內限制返回實體的距離或分數,以改善搜尋結果的相關性。在 Milvus 中,範圍搜尋涉及以與查詢向量最相似的向量嵌入為中心,畫出兩個同心圓。搜尋請求指定兩個圓圈的半徑,Milvus 會傳回屬於外圈但不屬於內圈的所有向量嵌入。
更多關於範圍搜尋,請參考範圍搜尋。
群組搜尋
如果返回的實體在特定欄位中持有相同的值,搜尋結果可能無法代表向量空間中所有向量內嵌的分佈。若要分散搜尋結果,請考慮使用群組搜尋。
關於群組搜尋的更多資訊,請參閱群組搜尋、
混合搜尋
一個集合可以包含多個向量場,以儲存使用不同嵌入模型產生的向量嵌入。如此一來,您就可以使用混合搜尋來重新排序這些向量欄位的搜尋結果,從而提高召回率。
有關混合搜尋的詳細資訊,請參閱混合搜尋。
搜尋迭代器
單一 ANN 搜尋最多會返回 16,384 個實體。如果您需要在單一搜尋中返回更多實體,請考慮使用搜尋迭接器。
有關搜尋迭接器的詳細資訊,請參閱搜尋迭接器。
全文本搜尋
全文檢索是一種在文字資料集中擷取包含特定詞彙或短語的文件,然後根據相關性排列結果的功能。此功能克服了語意搜尋可能會忽略精確詞彙的限制,確保您收到最精確且與上下文最相關的結果。此外,它還可以透過接受原始文字輸入來簡化向量搜尋,自動將您的文字資料轉換為稀疏嵌入,而不需要手動產生向量嵌入。
有關全文檢索的詳細資訊,請參閱全文檢索。
文字匹配
Milvus 中的關鍵字匹配功能可根據特定詞彙進行精確的文件檢索。此功能主要用於滿足特定條件的篩選搜尋,並可結合標量篩選來精細查詢結果,允許在符合標量條件的向量內進行相似性搜尋。
有關關鍵字匹配的詳細資訊,請參閱關鍵字匹配。
使用分割鍵
在元資料篩選中涉及多個標量欄位,並使用相當複雜的篩選條件,可能會影響搜尋效率。一旦將標量欄位設定為分割區金鑰,並在搜尋要求中使用涉及分割區金鑰的篩選條件,將有助於將搜尋範圍限制在與指定分割區金鑰值對應的分割區內。
有關分割區金鑰的詳細資訊,請參閱使用分割區金鑰。
使用 mmap
有關 mmap 設定的詳細資訊,請參閱使用 mmap。
叢集壓縮
有關群集壓縮的詳細資訊,請參閱群集壓縮。
使用排名器
有關使用排名器增強搜尋結果相關性的詳細資訊,請參閱Decay Ranker Overview和Model Ranker Overview。