vector-search
Milvus 기본 벡터 검색 (Basic Vector Search)
벡터 검색은 질문 벡터와 가장 가까운 벡터를 찾는 일이에요. Milvus는 ANN(Approximate Nearest Neighbor, 근사 최근접 이웃) 검색을 통해 전체 데이터를 전수 비교하지 않고도 효율적으로 top-K 결과를 돌려줍니다. ANN이 인덱스 파일을 기준 삼아 후보를 빠르게 좁힌 뒤, 지정한 거리 척도로 유사도를 재고 순위를 매기는 방식으로 동작해요.
이 페이지는 소스 문서 Milvus — Basic Vector Search 를 바탕으로, 기본적인 단일 벡터 검색을 수행하는 방법과 거리 척도별 특징을 정리해 드려요.
ANN과 kNN은 어떻게 다른가
벡터 유사도 검색에는 크게 두 가지 방법이 있어요.
- kNN(k-Nearest Neighbors) — 질문 벡터와 벡터 공간의 모든 벡터를 비교해 가장 가까운 것들을 찾습니다. 정확하지만 시간과 자원이 많이 들어요.
- ANN — 벡터 임베딩의 정렬 순서를 기록한 인덱스 파일을 활용합니다. 질문이 들어오면 인덱스를 참고해 질문 벡터와 가장 유사할 가능성이 있는 부분집합을 빠르게 찾고, 그 안에서 지정한 거리 척도(metric type) 로 유사도를 재서 top-K를 뽑아요.
ANN은 미리 만들어진 인덱스에 의존하며, 선택한 인덱스 타입에 따라 검색 처리량·메모리 사용·정확도가 달라져요. 그래서 검색 성능과 정확도를 균형 있게 조절해야 합니다.
배우는 부담을 줄이기 위해 Milvus는 **AUTOINDEX**를 제공해요. AUTOINDEX로 인덱스를 만들면 Milvus가 컬렉션 안 데이터 분포를 분석해, 성능과 정확도의 균형을 맞추는 최적의 인덱스 파라미터를 자동 설정해줍니다.
단일 벡터 검색
단일 벡터 검색은 검색 요청에 쿼리 벡터 하나만 담긴 경우예요. 아래 예시는 내적(IP)으로 유사도를 계산해 가장 가까운 3개를 반환합니다.
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="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': {}}
# ...
결과는 유사도 점수의 내림차순으로 정렬돼요. 이 유사도 점수를 질문 벡터까지의 거리(distance)라고도 부르며, 그 값의 범위는 거리 척도에 따라 달라져요.
거리 척도와 거리 범위
| 거리 척도 | 특징 | 거리 범위 |
|---|---|---|
L2 |
값이 작을수록 유사도 높음 | [0, ∞) |
IP |
값이 클수록 유사도 높음 | [-1, 1] |
COSINE |
값이 클수록 유사도 높음 | [-1, 1] |
JACCARD |
값이 작을수록 유사도 높음 | [0, 1] |
HAMMING |
값이 작을수록 유사도 높음 | [0, dim(vector)] |
거리 척도는 컬렉션 생성 시 벡터 필드에 설정한 값과 일치해야 정상적으로 해석할 수 있어요.
여러 벡터 검색 (Bulk-Vector Search)
검색 요청에 여러 쿼리 벡터를 포함할 수도 있어요. Milvus가 각 쿼리 벡터에 대해 ANN 검색을 병렬로 수행하고, 벡터별 결과 묶음을 반환합니다.
query_vectors = [
[0.041732933, 0.013779674, -0.027564144, -0.013061441, 0.009748648],
[0.0039737443, 0.003020432, -0.0006188639, 0.03913546, -0.00089768134],
]
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)
그 외 검색 유형
- 필터링 검색(Filtered Search) — 검색 전에 스칼라 필드 조건으로 후보를 좁혀 비용을 줄이고 정확도를 높입니다.
- 범위 검색(Range Search) — 반환되는 벡터의 거리·점수를 특정 범위로 제한합니다. 질문 벡터와 가장 유사한 벡터를 중심으로 안쪽 원과 바깥쪽 원 두 개를 그려, 바깥 원 안에 있으면서 안쪽 원 밖에 있는 벡터를 반환해요.
- 그룹핑 검색(Grouping Search) — 특정 필드에서 같은 값을 가진 엔티티가 많아 결과가 편중될 때, 결과를 다양화하기 위해 사용합니다.
- 하이브리드 검색(Hybrid Search) — 컬렉션에 여러 벡터 필드를 두고, 서로 다른 임베딩 모델로 만든 벡터들의 검색 결과를 재정렬해 재현율을 높입니다.
- 검색 이터레이터(Search Iterator) — 단일 ANN 검색은 최대 16,384개 엔티티까지만 반환해요. 더 많은 결과가 필요할 때 이터레이터를 사용합니다.
- 전문 검색(Full-Text Search) — 텍스트에서 특정 용어·구를 포함하는 문서를 찾고 관련도로 정렬합니다. 원시 텍스트를 받아 자동 희소 임베딩으로 바꾸므로 벡터를 직접 만들 필요가 없어요.
- 키워드 매치(Keyword Match) — 특정 용어로 정확한 문서를 찾는 기능. 주로 필터링 검색 조건으로 쓰이며 스칼라 필터와 결합해 사용합니다.
- 파티션 키(Partition Key) — 스칼라 필드를 파티션 키로 지정하면, 그 키를 포함한 필터 조건으로 검색 범위를 해당 파티션으로 제한해 효율을 높입니다.
실제 적용 (데이터스케쳐스)
- top-K 기본 — 질문을 임베딩해 쿼리 벡터로 만들고, 컬렉션에서 가장 가까운 K개 문서를 검색합니다.
- 거리 척도 일치 유지 — 컬렉션에 설정한 거리 척도와 검색
search_params의metric_type을 맞춰 일관된 점수를 얻습니다. - AUTOINDEX 기본 — 별도 튜닝 없이
AUTOINDEX로 데이터 분포에 맞는 인덱스를 자동 구성해 사용합니다.
더 알아보기
- 공식 문서 (1차): Basic Vector Search, Filtered Search, Range Search, Hybrid Search
- 큐레이션 (2차): Zilliz 블로그