컬렉션 (Collections)
컬렉션 (Collections)
컬렉션(collection)은 이름이 붙은 점(point)들의 집합이에요. 여기서 점이란 벡터와 그에 딸린 페이로드(payload)를 묶은 하나의 레코드를 뜻하고, 우리는 이 집합 안에서 검색을 수행합니다. 같은 컬렉션에 속한 각 점의 벡터는 반드시 **같은 차원(dimensionality)**을 가져야 하고, **하나의 거리 메트릭(metric)**으로 비교돼요. 이름 붙은 벡터(named vectors)를 쓰면 하나의 점 안에 여러 벡터를 둘 수 있는데, 이 경우 각 벡터는 자기만의 차원과 메트릭 요구사항을 가질 수 있습니다.
거리 메트릭은 벡터 사이의 유사도를 재는 기준이에요. 어떤 메트릭을 고를지는 벡터를 어떻게 얻었는지, 특히 신경망 인코더를 어떻게 훈련시켰는지에 따라 달라집니다.
Qdrant가 지원하는 가장 대중적인 메트릭 종류는 다음과 같아요.
- 점곱(Dot product):
Dot— 위키 - 코사인 유사도(Cosine similarity):
Cosine— 위키 - 유클리드 거리(Euclidean distance):
Euclid— 위키 - 맨해튼 거리(Manhattan distance):
Manhattan— 위키
검색 효율을 위해 코사인 유사도는 정규화된 벡터에 대한 점곱으로 구현돼요. 벡터는 업로드 과정에서 자동으로 정규화됩니다.
메트릭과 벡터 크기 외에도, 각 컬렉션은 컬렉션 최적화, 인덱스 구축, vacuum을 제어하는 자체 파라미터 집합을 사용합니다. 이 설정들은 언제든지 해당 요청으로 바꿀 수 있어요.
멀티테넌시 설정 (Setting Up Multitenancy)
컬렉션을 몇 개나 만들어야 할까요? 대부분의 경우 페이로드 기반 파티셔닝을 쓰는 단일 컬렉션 하나면 충분해요. 이 접근 방식을 멀티테넌시(multitenancy)라고 부르는데, 대부분의 사용자에게 효율적이지만 추가 구성이 필요해요. 설정 방법을 알아보려면 멀티테넌시 문서를 확인하세요.
그렇다면 언제 여러 컬렉션을 만들어야 할까요? 사용자 수가 적고 **격리(isolation)**가 필요할 때예요. 이 방식은 유연하지만 비용이 더 들 수 있어요. 컬렉션을 많이 만들면 리소스 오버헤드가 발생할 수 있거든요. 또 각 컬렉션이 성능 면에서도 서로 영향을 주지 않도록 신경 써야 합니다.
컬렉션 만들기 (Create a Collection)
PUT /collections/{collection_name}
{
"vectors": {
"size": 300,
"distance": "Cosine"
}
}
필수 옵션 외에도, 다음 컬렉션 옵션의 값을 직접 지정할 수 있어요.
hnsw_config— 자세한 내용은 인덱싱 문서를 확인하세요.wal_config— Write-Ahead-Log 관련 설정. WAL에 대한 자세한 내용은 WAL 문서를 참고하세요.optimizers_config— 자세한 내용은 옵티마이저 문서를 확인하세요.shard_number— 컬렉션이 몇 개의 샤드(shard)로 나뉘어야 하는지 정의해요. 자세한 내용은 분산 배포 섹션을 참고하세요.payload.memory— 페이로드 저장을 위한 메모리 티어(tier)를 설정해요.quantization_config— 자세한 내용은 양자화 문서를 확인하세요.strict_mode_config— 자세한 내용은 스트릭트 모드 문서를 확인하세요.
선택적 컬렉션 파라미터의 기본값은 구성 파일에 정의돼 있어요.
컬렉션과 벡터 파라미터에 대한 더 자세한 내용은 스키마 정의와 구성 파일을 참고하세요.
v1.2.0부터 사용 가능
Qdrant는 항상 벡터를 디스크에 저장해요. 벡터마다 메모리 티어를 설정해서 그 데이터 중 얼마나 많은 부분이 메모리에도 함께 상주할지를 제어할 수 있습니다.
여러 벡터를 가진 컬렉션 (Collection with Multiple Vectors)
v0.10.0부터 사용 가능
레코드 하나에 벡터를 여러 개 둘 수도 있어요. 이 기능 덕분에 컬렉션 하나에 여러 벡터 저장소를 둘 수 있습니다. 한 레코드 안의 벡터를 구분하려면 각 벡터에 고유한 이름을 붙여야 해요. 이 모드에서 각 이름 붙은 벡터는 자기만의 거리 메트릭과 크기를 가집니다.
PUT /collections/{collection_name}
{
"vectors": {
"image": {
"size": 4,
"distance": "Dot"
},
"text": {
"size": 8,
"distance": "Cosine"
}
}
}
드물긴 하지만 벡터 저장소가 전혀 없는 컬렉션을 만들 수도 있어요.
v1.1.1부터 사용 가능
각 이름 붙은 벡터에 대해 hnsw_config나 quantization_config를 선택적으로 지정해서 컬렉션 기본 설정과 다르게 둘 수 있어요. 벡터 수준에서 검색 성능을 미세 조정할 때 유용합니다.
v1.2.0부터 사용 가능
Qdrant는 항상 벡터를 디스크에 저장해요. 벡터 단위로 메모리 티어를 설정해서 그 데이터 중 얼마나 많은 부분이 메모리에도 함께 상주할지를 제어할 수 있습니다.
벡터 데이터 타입 (Vector Datatypes)
v1.9.0부터 사용 가능
기본적으로 Qdrant는 각 벡터 차원을 **32비트 부동소수점(float)**으로 저장해요. 메모리와 저장 공간은 차원 수에 비례해 늘어나므로, 벡터가 크면 이 비용이 빠르게 쌓입니다. 이 비용을 줄이거나 이미 더 낮은 정밀도의 벡터를 저장하려면 다른 데이터 타입을 설정할 수 있어요: float16(반정밀도), uint8(부호 없는 8비트 정수), turbo4(4비트)가 있습니다.
예를 들어 uint8 임베딩으로 컬렉션을 만들려면 이렇게 해요.
PUT /collections/{collection_name}
{
"vectors": {
"size": 1024,
"distance": "Cosine",
"datatype": "uint8"
}
}
전체 옵션과 각각의 트레이드오프는 데이터 타입 문서를 참고하세요.
희소 벡터 컬렉션 (Collection with Sparse Vectors)
v1.7.0부터 사용 가능
Qdrant는 희소 벡터(sparse vector)를 **일급 시민(first-class citizen)**으로 지원해요.
희소 벡터는 텍스트 검색에 유용해요. 각 단어가 하나의 별도 차원으로 표현되거든요.
컬렉션은 일반적인 밀집 벡터(dense vector) 옆에 추가적인 이름 붙은 벡터로 희소 벡터를 포함할 수 있어요. 하나의 점 안에 함께 둘 수 있습니다.
밀집 벡터와 달리 희소 벡터는 반드시 이름을 가져야 해요. 또 희소 벡터와 밀집 벡터는 한 컬렉션 안에서 서로 다른 이름을 가져야 합니다.
PUT /collections/{collection_name}
{
"sparse_vectors": {
"text": { }
}
}
고유한 이름 외에 희소 벡터에 요구되는 필수 구성 파라미터는 없어요.
희소 벡터의 거리 함수는 항상 Dot이라 따로 지정할 필요가 없습니다.
다만, 희소 벡터 인덱스의 기반을 조정하는 선택적 파라미터는 있습니다.
다른 컬렉션에서 컬렉션 만들기 (Create Collection from Another Collection)
다른 컬렉션에서 컬렉션을 만들려면 **마이그레이션 도구(migration tool)**를 사용해요. 같은 Qdrant 인스턴스 안에서 컬렉션을 복사하거나, 다른 인스턴스로 컬렉션을 복사하는 데 쓸 수 있습니다.
예를 들어 로컬 인스턴스의 컬렉션을 Qdrant Cloud 인스턴스로 복사하려면 다음 명령을 실행해요.
docker run --net=host --rm -it registry.cloud.qdrant.io/library/qdrant-migration qdrant \
--source.url 'http://localhost:6334' \
--source.collection 'source-collection' \
--target.url 'https://example.cloud-region.cloud-provider.cloud.qdrant.io:6334' \
--target.api-key 'qdrant-key' \
--target.collection 'target-collection' \
--migration.batch-size 64
컬렉션 존재 여부 확인 (Check Collection Existence)
v1.8.0부터 사용 가능
GET /collections/{collection_name}/exists
컬렉션 삭제 (Delete Collection)
DELETE /collections/{collection_name}
컬렉션 업데이트 (Update Collection)
컬렉션을 만든 뒤에는 그 구성, 벡터, 그리고 벡터의 구성을 바꿀 수 있어요.
컬렉션 파라미터 업데이트 (Update Collection Parameters)
동적 파라미터 업데이트는 예를 들어 벡터의 초기 로딩을 더 효율적으로 만들 때 유용해요. 업로드 과정에서는 인덱싱을 끄고, 업로드가 끝나자마자 다시 켜는 식이죠. 이렇게 하면 인덱스를 다시 만드는 데 불필요한 계산 자원을 낭비하지 않게 됩니다.
다음 명령은 10000 kB 이상의 벡터를 저장한 세그먼트에 대해 인덱싱을 활성화해요.
PATCH /collections/{collection_name}
{
"optimizers_config": {
"indexing_threshold": 10000
}
}
다음 파라미터들은 업데이트할 수 있어요.
optimizers_config— 자세한 내용은 옵티마이저 문서를 참고하세요.hnsw_config— 자세한 내용은 인덱싱 문서를 참고하세요.quantization_config— 자세한 내용은 양자화 문서를 참고하세요.vectors_config— 벡터별 구성. 개별hnsw_config,quantization_config, 메모리 티어 설정을 포함해요.params— 기타 컬렉션 파라미터.read_fan_out_delay_ms,write_consistency_factor, 페이로드의 메모리 티어를 포함해요.strict_mode_config— 자세한 내용은 스트릭트 모드 문서를 참고하세요.
전체 API 사양은 스키마 정의에서 확인할 수 있어요.
이 엔드포인트에 대한 호출은 **기존 옵티마이저가 끝나기를 기다리므로 블로킹(blocking)**일 수 있어요. 인덱스를 다시 만드는 데 따른 큰 오버헤드가 발생할 수 있으므로, 프로덕션 데이터베이스에서는 사용을 권장하지 않습니다.
벡터 스키마 업데이트 (Update Vector Schema)
v1.18.0부터 사용 가능
이름 붙은 벡터는 컬렉션을 다시 만들지 않고도 기존 컬렉션에 추가하거나 제거할 수 있어요. 이는 임베딩 모델 마이그레이션에 유용해요. 새 모델용 벡터를 추가하고, 백그라운드에서 점들을 다시 임베딩한 뒤, 준비되면 이전 벡터를 제거하면 됩니다.
이들은 컬렉션 스키마에서 벡터 정의를 추가하거나 제거하는 스키마 수준(schema-level)의 연산이에요. 특정 점에 벡터 값을 추가/제거하려면 벡터 업데이트·삭제 연산을 사용하세요.
기존 컬렉션에 새 밀집 이름 벡터를 추가하려면:
PUT /collections/{collection_name}/vectors/{vector_name}
{
"dense": {
"size": 256,
"distance": "Cosine"
}
}
기존 컬렉션에 새 희소 이름 벡터를 추가하려면:
PUT /collections/{collection_name}/vectors/{vector_name}
{
"sparse": {
"modifier": "Idf"
}
}
요청 본문은 벡터 공간을 정의하는 속성만 받아요(밀집 벡터의 경우 size와 distance). 양자화, 저장 타입, 인덱스 구성은 이후에 컬렉션 파라미터 업데이트나 벡터 파라미터 업데이트 API로 설정할 수 있어요.
기존 점들은 다시 업서트(upsert)되기 전까지는 새로 추가된 벡터에 대한 값을 갖지 않아요. 새 벡터는 즉시 쿼리할 수 있지만, 값이 채워지기 전까지는 결과를 반환하지 않습니다.
기존 컬렉션에서 이름 붙은 벡터를 삭제하려면:
DELETE /collections/{collection_name}/vectors/{vector_name}
이름 붙은 벡터를 삭제하면 그 스키마와 관련 데이터가 모두 제거돼요. 기존 점들은 그 외에는 영향을 받지 않습니다.
벡터 파라미터 업데이트 (Update Vector Parameters)
v1.4.0부터 사용 가능
컬렉션 업데이트 API로 벡터 파라미터를 업데이트할 때는 항상 벡터 이름을 지정해야 해요. 컬렉션에 이름 붙은 벡터가 없다면 빈 이름("")을 사용합니다.
Qdrant 1.4는 더 많은 컬렉션 파라미터를 런타임에 업데이트하는 것을 지원해요. HNSW 인덱스, 양자화, 디스크 구성은 이제 컬렉션을 다시 만들지 않고도 바꿀 수 있어요. 세그먼트(인덱스와 양자화 데이터 포함)는 업데이트된 파라미터에 맞춰 백그라운드에서 자동으로 다시 구축됩니다.
이름 붙은 벡터가 없는 컬렉션의 벡터 데이터를 콜드 메모리 티어로 옮기려면 이름으로 ""을 사용해요.
PATCH /collections/{collection_name}
{
"vectors": {
"": {
"memory": "cold"
}
}
}
이름 붙은 벡터가 있는 컬렉션의 벡터 데이터를 콜드 메모리 티어로 옮기려면:
참고: 벡터 이름을 만들려면 Points 문서의 절차를 따르세요.
PATCH /collections/{collection_name}
{
"vectors": {
"my_vector": {
"memory": "cold"
}
}
}
다음 예시에서는 HNSW 인덱스와 양자화 파라미터를 컬렉션 전체와 my_vector 각각에 대해 업데이트해요.
PATCH /collections/{collection_name}
{
"vectors": {
"my_vector": {
"hnsw_config": {
"m": 32,
"ef_construct": 123
},
"quantization_config": {
"product": {
"compression": "x32",
"memory": "pinned"
}
},
"memory": "cold"
}
},
"hnsw_config": {
"ef_construct": 123
},
"quantization_config": {
"scalar": {
"type": "int8",
"quantile": 0.8,
"memory": "cached"
}
}
}
컬렉션 정보 (Collection Info)
Qdrant는 기존 컬렉션의 구성 파라미터를 조회해서 점들이 어떻게 분포되고 인덱싱되는지 더 잘 이해할 수 있게 해줘요.
GET /collections/{collection_name}
예상 결과
컬렉션에 벡터를 삽입하면, 최적화가 진행되는 동안 status 필드가 노란색이 될 수 있어요. 모든 점이 성공적으로 처리되면 초록색이 됩니다.
가능한 색상 상태는 다음과 같아요.
- 🟢 초록(green): 컬렉션이 준비됨
- 🟡 노랑(yellow): 컬렉션이 최적화 중
- ⚫ 회색(grey): 컬렉션이 최적화 대기 중 (도움말)
- 🔴 빨강(red): 엔진이 복구할 수 없는 오류 발생
회색 컬렉션 상태 (Grey Collection Status)
v1.9.0부터 사용 가능
컬렉션이 ⚫ 회색 상태이거나 최적화 상태로 "optimizations pending, awaiting update operation"(최적화 보류, 업데이트 연산 대기 중)을 보여줄 수 있어요. 이 상태는 보통 최적화가 진행 중일 때 Qdrant 인스턴스를 재시작해서 발생합니다.
즉, 이 컬렉션에는 보류 중인 최적화가 있는데 일시 정지된 상태예요. 최적화를 다시 시작하려면 아무 업데이트 연산이나 보내야 합니다.
예를 들어:
PATCH /collections/{collection_name}
{
"optimizers_config": {}
}
또는 Qdrant Web UI의 Trigger Optimizers 버튼을 사용할 수도 있어요. 컬렉션 정보 페이지의 회색 상태 옆에 표시됩니다.
점·벡터 개수의 근사치 (Approximate Point and Vector Counts)
count 속성이 궁금할 수 있어요.
points_count— 컬렉션에 저장된 객체(벡터와 그 페이로드)의 총 개수indexed_vectors_count— HNSW 또는 희소 인덱스에 저장된 벡터의 총 개수. Qdrant는 모든 벡터를 인덱스에 저장하지 않아요. 주어진 구성에 대해 인덱스 세그먼트가 만들어질 수 있을 때만 저장합니다.
위 개수는 정확한 값이 아니라 근사치로 봐야 해요. Qdrant를 어떻게 쓰느냐에 따라 기대했던 값과 아주 다르게 나올 수 있습니다. 그러니 이것에 의존하지 않는 게 중요해요.
좀 더 자세히 말하면, 이 숫자들은 Qdrant 내부 저장소에 있는 점과 벡터의 개수를 나타내요. 내부적으로 Qdrant는 자동 최적화의 일부로 점을 일시적으로 중복할 수 있고, 변경되거나 삭제된 점을 잠시 유지할 수 있으며, 새 점의 인덱싱을 지연할 수 있어요. 이 모두 최적화를 위한 것입니다.
그래서 사용자가 수행한 업데이트가 이 숫자에 바로 반영되지는 않아요. 점 개수가 예상과 크게 다르게 보여도, 한 차례의 자동 최적화가 끝나면 대개 해결됩니다.
명확히 하자면, 이 숫자들은 삽입한 점·벡터의 정확한 개수도 아니고, 쿼리할 수 있는 구분 가능한 점·벡터의 정확한 개수도 아니에요. 정확한 개수가 필요하다면 count API를 사용하세요.
참고: 이 숫자들은 Qdrant의 향후 버전에서 제거될 수 있어요.
HNSW에서 벡터 인덱싱 (Indexing Vectors in HNSW)
가끔은 indexed_vectors_count 값이 기대보다 낮아서 놀랄 수 있어요. 이는 의도된 동작이고 옵티마이저 구성에 따라 달라져요. 인덱스되지 않은 벡터의 크기가 indexing_threshold(kB 단위) 값보다 크면 새 인덱스 세그먼트가 만들어집니다. 컬렉션이 아주 작거나 벡터 차원이 낮으면 HNSW 세그먼트가 전혀 만들어지지 않아서 indexed_vectors_count가 0일 수 있어요.
기존 컬렉션의 indexing_threshold를 줄이려면 컬렉션 파라미터를 업데이트하면 됩니다.
컬렉션 메타데이터 (Collection Metadata)
v1.16.0부터 사용 가능
편의와 데이터 조직화를 위해 Qdrant는 컬렉션에 키-값 쌍 형태의 커스텀 메타데이터를 붙일 수 있게 해줘요. 메타데이터 추가는 컬렉션 구성의 일부로 취급되며, 합의 프로토콜(consensus protocol)을 통해 클러스터의 모든 노드에 동기화됩니다.
컬렉션 메타데이터는 컬렉션 생성 시 지정할 수 있고:
PUT /collections/{collection_name}
{
"vectors": {
"size": 300,
"distance": "Cosine"
},
"metadata": {
"my-metadata-field": "value-1",
"another-field": 123
}
}
이후에도 업데이트할 수 있어요.
PATCH /collections/{collection_name}
{
"metadata": {
"my-metadata-field": {
"key-a": "value-a",
"key-b": 42
}
}
}
참고로 업데이트 연산은 지정한 메타데이터 필드만 수정하고 나머지 필드는 그대로 둡니다.
지정하면 메타데이터는 컬렉션 정보의 일부로 반환돼요.
{
"result": {
"config": {
"metadata": {
"my-metadata-field": {
"key-a": "value-a",
"key-b": 42
},
"another-field": 123
}
}
}
}
컬렉션 별칭 (Collection Aliases)
프로덕션 환경에서는 서로 다른 벡터 버전을 무중단으로 전환해야 할 때가 있어요. 예를 들어 신경망의 새 버전으로 업그레이드할 때죠.
이런 상황에서 서비스를 멈추고 새 벡터로 컬렉션을 다시 빌드할 방법은 없어요. 별칭(alias)은 기존 컬렉션의 추가 이름이에요. 컬렉션에 대한 모든 쿼리는 컬렉션 이름 대신 별칭을 써서 동일하게 수행할 수 있습니다.
그래서 두 번째 컬렉션을 백그라운드에서 빌드한 뒤, 별칭을 이전 컬렉션에서 새 컬렉션으로 전환할 수 있어요. 별칭의 모든 변경은 **원자적(atomic)**으로 일어나므로, 전환 중에 동시 요청이 영향을 받지 않습니다.
별칭 만들기 (Create Alias)
POST /collections/aliases
{
"actions": [
{
"create_alias": {
"collection_name": "example_collection",
"alias_name": "production_collection"
}
}
]
}
별칭 제거 (Remove Alias)
POST /collections/aliases
{
"actions": [
{
"delete_alias": {
"alias_name": "production_collection"
}
}
]
}
컬렉션 전환 (Switch Collection)
여러 별칭 연산은 원자적으로 수행됩니다. 예를 들어 다음 명령으로 기본 컬렉션을 전환할 수 있어요.
POST /collections/aliases
{
"actions": [
{
"delete_alias": {
"alias_name": "production_collection"
}
},
{
"create_alias": {
"collection_name": "example_collection",
"alias_name": "production_collection"
}
}
]
}
컬렉션 별칭 목록 (List Collection Aliases)
GET /collections/{collection_name}/aliases
모든 별칭 목록 (List All Aliases)
GET /aliases
모든 컬렉션 목록 (List All Collections)
GET /collections