범위 검색
범위 검색은 특정 범위 내에서 반환되는 엔티티의 거리 또는 점수를 제한하여 검색 결과의 관련성을 향상시킵니다. 이 페이지에서는 범위 검색의 정의와 범위 검색을 수행하는 절차에 대한 이해를 돕습니다.
개요
밀버스는 범위 검색 요청을 실행할 때 ANN 검색 결과에서 쿼리 벡터와 가장 유사한 벡터를 중심으로 삼고, 검색 요청에 지정된 반경을 바깥쪽 원의 반경으로, 범위_필터를 안쪽 원의 반경으로 하여 동심원 두 개를 그립니다. 이 두 동심원으로 형성된 환형 영역에 속하는 유사도 점수가 있는 모든 벡터가 반환됩니다. 여기서 range_filter를 0으로 설정하면 지정된 유사도 점수(반경) 내의 모든 엔티티가 반환됩니다.
범위 검색
위 다이어그램은 범위 검색 요청에 두 개의 매개변수, 즉 반경과 범위_필터가 포함됨을 보여줍니다. 범위 검색 요청을 받으면 Milvus는 다음을 수행합니다:
지정된 메트릭 유형(COSINE)을 사용하여 쿼리 벡터와 가장 유사한 모든 벡터 임베딩을 찾습니다.
쿼리 벡터와의 거리 또는 점수가 radius 및 range_filter 매개변수로 지정된 범위 내에 속하는 벡터 임베딩을 필터링합니다.
필터링된 엔티티 중에서 상위 K개의 엔티티를 반환합니다.
반경 및 범위_필터를 설정하는 방법은 검색의 메트릭 유형에 따라 다릅니다. 다음 표에는 서로 다른 메트릭 유형으로 이 두 매개변수를 설정하기 위한 요구사항이 나와 있습니다.
메트릭 유형 |
표시 |
반경 및 범위_필터 설정 요구 사항 |
|---|---|---|
|
L2 거리가 작을수록 유사성이 높음을 나타냅니다. |
가장 유사한 벡터 임베딩을 무시하려면 다음을 확인합니다.
|
|
IP 거리가 클수록 유사도가 높음을 나타냅니다. |
가장 유사한 벡터 임베딩을 무시하려면 다음을 확인합니다.
|
|
코사인 거리가 클수록 유사도가 높음을 나타냅니다. |
가장 유사한 벡터 임베딩을 무시하려면 다음을 확인합니다.
|
|
자카드 거리가 작을수록 유사도가 높음을 나타냅니다. |
가장 유사한 벡터 임베딩을 무시하려면 다음을 확인합니다.
|
|
해밍 거리가 작을수록 유사도가 높다는 것을 나타냅니다. |
가장 유사한 벡터 임베딩을 무시하려면 다음을 확인합니다.
|
예제
이 섹션에서는 범위 검색을 수행하는 방법을 설명합니다. 다음 코드 스니펫의 검색 요청에는 메트릭 유형이 포함되어 있지 않아 기본 메트릭 유형인 COSINE이 적용됩니다. 이 경우 반경 값이 범위_필터 값보다 작은지 확인하세요.
다음 코드 조각에서 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={
"params": {
"radius": 0.4,
"range_filter": 0.6
}
}
)
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("my_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)
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v2/index"
"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"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: milvusAddr,
})
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}
annParam := index.NewCustomAnnParam()
annParam.WithRadius(0.4)
annParam.WithRangeFilter(0.6)
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"my_collection", // collectionName
5, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithConsistencyLevel(entity.ClStrong).
WithANNSField("vector").
WithAnnParam(annParam))
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});
var query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = await client.search({
collection_name: "my_collection",
data: [query_vector],
limit: 5,
params: {
"radius": 0.4,
"range_filter": 0.6
}
})
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": "my_collection",
"data": [
[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
],
"annsField": "vector",
"limit": 5,
"searchParams": {
"params": {
"radius": 0.4,
"range_filter": 0.6
}
}
}'
# {"code":0,"cost":0,"data":[]}
쿼리 벡터가 대상 컬렉션에 이미 존재하는 경우, 검색 전에 검색 벡터를 검색하는 대신 ids 을 사용하는 것을 고려하세요. 자세한 내용은 기본 키 검색을 참조하세요.