milvus-logo
LFAI
홈페이지
  • 사용자 가이드

기본 ANN 검색

벡터 임베딩의 정렬된 순서를 기록한 인덱스 파일을 기반으로 하는 ANN(근사 최인접 이웃) 검색은 수신된 검색 요청에 포함된 쿼리 벡터를 기반으로 벡터 임베딩의 하위 집합을 찾고, 쿼리 벡터와 하위 그룹에 있는 벡터를 비교하여 가장 유사한 결과를 반환합니다. 밀버스는 ANN 검색을 통해 효율적인 검색 환경을 제공합니다. 이 페이지에서는 기본적인 ANN 검색을 수행하는 방법을 알아볼 수 있습니다.

개요

ANN과 kNN(k-Nearest Neighbors) 검색은 벡터 유사도 검색의 일반적인 방법입니다. kNN 검색에서는 벡터 공간의 모든 벡터를 검색 요청에 포함된 쿼리 벡터와 비교하여 가장 유사한 벡터를 찾아내야 하므로 시간과 리소스가 많이 소요됩니다.

kNN 검색과 달리 ANN 검색 알고리즘은 벡터 임베딩의 정렬된 순서를 기록하는 인덱스 파일을 요청합니다. 검색 요청이 들어오면 인덱스 파일을 참조로 사용해 쿼리 벡터와 가장 유사한 벡터 임베딩이 포함된 하위 그룹을 빠르게 찾을 수 있습니다. 그런 다음 지정된 메트릭 유형을 사용하여 쿼리 벡터와 하위 그룹의 벡터 간의 유사성을 측정하고, 쿼리 벡터와의 유사성을 기준으로 그룹 구성원을 정렬하고, 상위 K 개의 그룹 구성원을 파악할 수 있습니다.

ANN 검색은 미리 구축된 인덱스에 따라 달라지며, 검색 처리량, 메모리 사용량 및 검색 정확도는 선택한 인덱스 유형에 따라 달라질 수 있습니다. 검색 성능과 정확성 간의 균형을 맞춰야 합니다.

학습 곡선을 줄이기 위해 Milvus는 AUTOINDEX를 제공합니다. 자동 인덱스는 인덱스를 구축하는 동안 컬렉션 내의 데이터 분포를 분석하고 분석 결과에 따라 가장 최적화된 인덱스 파라미터를 설정하여 검색 성능과 정확성 간의 균형을 맞출 수 있습니다.

자동 인덱스 및 적용 가능한 메트릭 유형에 대한 자세한 내용은 자동 인덱스메트릭 유형을 참조하세요. 이 섹션에서는 다음 주제에 대한 자세한 정보를 확인할 수 있습니다.

ANN 검색에서 단일 벡터 검색은 하나의 쿼리 벡터만 포함하는 검색을 말합니다. 미리 구축된 인덱스와 검색 요청에 포함된 메트릭 유형에 따라 Milvus는 쿼리 벡터와 가장 유사한 상위 K개의 벡터를 찾습니다.

이 섹션에서는 단일 벡터 검색을 수행하는 방법을 배웁니다. 코드 조각은 빠른 설정 방식으로 컬렉션을 생성했다고 가정합니다. 검색 요청은 단일 쿼리 벡터를 전달하고 Milvus에 내적 곱(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="my_collection",
    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("my_collection")
        .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.95944905, id=5)
// SearchResp.SearchResult(entity={}, score=0.8689616, id=1)
// SearchResp.SearchResult(entity={}, score=0.866088, id=7)

import (
    "context"
    "fmt"
    "log"

    "github.com/milvus-io/milvus/client/v2"
    "github.com/milvus-io/milvus/client/v2/entity"
)

func ExampleClient_Search_basic() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    milvusAddr := "127.0.0.1:19530"
    token := "root:Milvus"

    cli, err := client.New(ctx, &client.ClientConfig{
        Address: milvusAddr,
        APIKey:  token,
    })
    if err != nil {
        log.Fatal("failed to connect to milvus server: ", err.Error())
    }

    defer cli.Close(ctx)

    queryVector := []float32{0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592}

    resultSets, err := cli.Search(ctx, client.NewSearchOption(
        "my_collection", // collectionName
        3,             // limit
        []entity.Vector{entity.FloatVector(queryVector)},
    ))
    if err != nil {
        log.Fatal("failed to perform basic ANN search collection: ", err.Error())
    }

    for _, resultSet := range resultSets {
        log.Println("IDs: ", resultSet.IDs)
        log.Println("Scores: ", resultSet.Scores)
    }
    // Output:
    // IDs:
    // 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: "my_collection",
    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" \
-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는 쿼리 벡터와의 유사도 점수에 따라 검색 결과의 순위를 내림차순으로 매깁니다. 유사도 점수는 쿼리 벡터와의 거리라고도 하며, 그 값 범위는 사용 중인 메트릭 유형에 따라 달라집니다.

다음 표에는 적용 가능한 메트릭 유형과 해당 거리 범위가 나와 있습니다.

메트릭 유형

특성

거리 범위

L2

값이 작을수록 유사성이 높음을 나타냅니다.

[0, ∞)

IP

값이 클수록 유사도가 높음을 나타냅니다.

[-1, 1]

COSINE

값이 클수록 유사도가 높음을 나타냅니다.

[-1, 1]

JACCARD

값이 작을수록 유사도가 높음을 나타냅니다.

[0, 1]

HAMMING

값이 작을수록 유사도가 높음을 나타냅니다.

[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="my_collection",
    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)

// 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: 5,
})

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" \
-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
#           }
#        ]
#     ]
# }

파티션에서 ANN 검색

컬렉션에 여러 개의 파티션을 만들었고 검색 범위를 특정 수의 파티션으로 좁힐 수 있다고 가정해 보겠습니다. 이 경우 검색 요청에 대상 파티션 이름을 포함하여 지정된 파티션 내에서 검색 범위를 제한할 수 있습니다. 검색에 관련된 파티션 수를 줄이면 검색 성능이 향상됩니다.

다음 코드 스니펫은 컬렉션에 PartitionA라는 이름의 파티션이 있다고 가정합니다.

# 4. Single vector search
query_vector = [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
res = client.search(
    collection_name="my_collection",
    # highlight-next-line
    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)

// 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",
    // highlight-next-line
    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" \
-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
#         }
#     ]
# }

출력 필드 사용

검색 결과에서 Milvus는 기본적으로 상위 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"},
    # highlight-next-line
    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)

// 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
    // highlight-next-line
    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" \
-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"
#         }
#     ]
# }

제한 및 오프셋 사용

검색 요청에 포함된 limit 매개변수는 검색 결과에 포함할 엔티티의 수를 결정합니다. 이 매개변수는 단일 검색에서 반환할 최대 엔티티 수를 지정하며, 일반적으로 top-K라고 합니다.

페이지 매김 쿼리를 수행하려는 경우 루프를 사용하여 여러 개의 검색 요청을 보내고 각 쿼리 요청에 제한오프셋 매개변수를 전달할 수 있습니다. 구체적으로, 현재 쿼리 결과에 포함하려는 엔티티의 수로 Limit 매개변수를 설정하고, 이미 반환된 엔티티의 총 수로 Offset을 설정할 수 있습니다.

아래 표에는 한 번에 100개의 엔티티를 반환할 때 페이지 매김 쿼리에 대한 제한오프셋 매개변수를 설정하는 방법이 간략하게 설명되어 있습니다.

쿼리

쿼리당 반환할 엔티티 수

이미 반환된 총 엔티티 수

첫 번째 쿼리

100

0

두 번째 쿼리

100

100

세 번째 쿼리

100

200

n번째 쿼리

100

100 x (n-1)

단일 ANN 검색에서 limitoffset 의 합은 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", 
        # highlight-next-line
        "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)

// 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,
    // highlight-next-line
    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" \
-d '{
    "collectionName": "quick_setup",
    "data": [
        [0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]
    ],
    "annsField": "vector",
    "limit": 3,
    "offset": 10
}'

자동 인덱스는 ANN 검색의 학습 곡선을 상당히 평탄화합니다. 그러나 상위-K가 증가함에 따라 검색 결과가 항상 정확하지 않을 수 있습니다. 검색 범위를 줄이고, 검색 결과 관련성을 개선하고, 검색 결과를 다양화함으로써 Milvus는 다음과 같은 검색 개선 작업을 수행합니다.

  • 필터링 검색

    검색 요청에 필터링 조건을 포함하면 Milvus가 ANN 검색을 수행하기 전에 메타데이터 필터링을 수행하여 검색 범위를 전체 컬렉션에서 지정된 필터링 조건과 일치하는 엔티티로만 축소할 수 있습니다.

    메타데이터 필터링 및 필터링 조건에 대한 자세한 내용은 필터링된 검색메타데이터 필터링을 참조하세요.

  • 범위 검색

    특정 범위 내에서 반환되는 엔티티의 거리 또는 점수를 제한하여 검색 결과 관련성을 향상시킬 수 있습니다. Milvus에서 범위 검색은 쿼리 벡터와 가장 유사한 벡터가 포함된 동심원을 중심으로 두 개의 동심원을 그리는 방식으로 이루어집니다. 검색 요청은 두 원의 반지름을 지정하며, Milvus는 바깥쪽 원에 속하지만 안쪽 원에 속하지 않는 모든 벡터 임베딩을 반환합니다.

    범위 검색에 대한 자세한 내용은 범위 검색을 참조하세요.

  • 그룹 검색

    반환된 엔티티가 특정 필드에서 동일한 값을 갖는 경우 검색 결과가 벡터 공간에 있는 모든 벡터 임베딩의 분포를 나타내지 않을 수 있습니다. 검색 결과를 다양화하려면 그룹화 검색을 사용해 보세요.

    그룹화 검색에 대한 자세한 내용은 그룹화 검색을 참조하세요.

  • 하이브리드 검색

    컬렉션에는 서로 다른 임베딩 모델을 사용하여 생성된 벡터 임베딩을 저장하기 위해 최대 4개의 벡터 필드를 포함할 수 있습니다. 이렇게 하면 하이브리드 검색을 사용하여 이러한 벡터 필드에서 검색 결과의 순위를 재조정하여 재검색률을 높일 수 있습니다.

    하이브리드 검색에 대한 자세한 내용은 하이브리드 검색을 참조하세요.

  • 검색 이터레이터

    단일 ANN 검색은 최대 16,384개의 엔티티를 반환합니다. 한 번의 검색으로 더 많은 엔티티를 반환해야 하는 경우 검색 반복기를 사용하는 것을 고려하세요.

    검색 반복기에 대한 자세한 내용은 검색 반복기를 참조하세요.

  • 전체 텍스트 검색

    전체 텍스트 검색은 텍스트 데이터 세트에서 특정 용어나 구문이 포함된 문서를 검색한 다음 관련성에 따라 결과의 순위를 매기는 기능입니다. 이 기능은 정확한 용어를 놓칠 수 있는 시맨틱 검색의 한계를 극복하여 가장 정확하고 문맥과 연관성이 높은 결과를 얻을 수 있도록 해줍니다. 또한, 원시 텍스트 입력을 받아 벡터 임베딩을 수동으로 생성할 필요 없이 텍스트 데이터를 스파스 임베딩으로 자동 변환하여 벡터 검색을 간소화합니다.

    전체 텍스트 검색에 대한 자세한 내용은 전체 텍스트 검색을 참조하세요.

  • 텍스트 일치

    Milvus의 텍스트 일치를 사용하면 특정 용어를 기반으로 정확한 문서 검색이 가능합니다. 이 기능은 주로 특정 조건을 충족하는 필터링 검색에 사용되며, 스칼라 필터링을 통합하여 쿼리 결과를 구체화함으로써 스칼라 기준을 충족하는 벡터 내에서 유사성 검색을 할 수 있습니다.

    텍스트 일치에 대한 자세한 내용은 텍스트 일치를 참조하세요.

  • 파티션 키 사용

    메타데이터 필터링에 여러 개의 스칼라 필드를 포함시키고 다소 복잡한 필터링 조건을 사용하면 검색 효율성에 영향을 미칠 수 있습니다. 스칼라 필드를 파티션 키로 설정하고 검색 요청에 파티션 키와 관련된 필터링 조건을 사용하면 지정된 파티션 키 값에 해당하는 파티션 내에서 검색 범위를 제한하는 데 도움이 될 수 있습니다.

    파티션 키에 대한 자세한 내용은 파티션 키 사용을 참조하세요.

  • mmap 사용

    Milvus에서 메모리 매핑 파일을 사용하면 파일 내용을 메모리에 직접 매핑할 수 있습니다. 이 기능은 특히 사용 가능한 메모리가 부족하지만 완전한 데이터 로딩이 불가능한 상황에서 메모리 효율성을 향상시킵니다. 이 최적화 메커니즘은 일정 한도까지 성능을 보장하면서 데이터 용량을 늘릴 수 있지만 데이터 양이 메모리를 너무 많이 초과하면 검색 및 쿼리 성능이 심각하게 저하될 수 있으므로 이 기능을 적절히 켜거나 끄도록 선택하세요.

    mmap 설정에 대한 자세한 내용은 mmap 사용을 참조하세요.

  • 클러스터링 압축

    클러스터링 압축은 대규모 컬렉션에서 검색 성능을 개선하고 비용을 절감하기 위해 고안된 기능입니다. 이 가이드는 클러스터링 압축을 이해하고 이 기능으로 검색 성능을 개선하는 방법을 이해하는 데 도움이 됩니다.

    클러스터링 압축에 대한 자세한 내용은 클러스터링 압축을 참조하세요.

번역DeepLogo

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
피드백

이 페이지가 도움이 되었나요?