集合
集合是点的命名集合(带有有效载荷的向量),您可以在其中进行搜索。同一集合中每个点的向量必须具有相同的维度,并使用单一指标进行比较。命名向量可用于在单个点中包含多个向量,每个向量可以有自己的维度和指标要求。
距离指标用于衡量向量之间的相似性。指标的选择取决于获取向量的方式,特别是神经网络编码器训练的方法。
Qdrant 支持以下最常见的指标类型
除了指标和向量大小,每个集合还使用自己的参数集,用于控制集合优化、索引构建和空间清理。这些设置可以通过相应的请求随时更改。
设置多租户
应该创建多少个集合? 在大多数情况下,您应该只使用一个基于有效载荷分区的集合。这种方法称为多租户。它对大多数用户来说是高效的,但需要额外的配置。了解如何设置
何时应该创建多个集合? 当您用户数量有限且需要隔离时。这种方法很灵活,但也可能成本更高,因为创建大量集合可能会导致资源开销。此外,您需要确保它们之间不会以任何方式互相影响,包括性能方面。
创建集合
PUT /collections/{collection_name}
{
"vectors": {
"size": 300,
"distance": "Cosine"
}
}
curl -X PUT http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"size": 300,
"distance": "Cosine"
}
}'
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=100, distance=models.Distance.COSINE),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: { size: 100, distance: "Cosine" },
});
use qdrant_client::Qdrant;
use qdrant_client::qdrant::{CreateCollectionBuilder, VectorParamsBuilder};
let client = Qdrant::from_url("http://localhost:6334").build()?;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(100, Distance::Cosine)),
)
.await?;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client.createCollectionAsync("{collection_name}",
VectorParams.newBuilder().setDistance(Distance.Cosine).setSize(100).build()).get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams { Size = 100, Distance = Distance.Cosine }
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
Size: 100,
Distance: qdrant.Distance_Cosine,
}),
})
除了必需的选项外,您还可以为以下集合选项指定自定义值
hnsw_config
- 详情请参见索引。wal_config
- 与预写日志相关的配置。详情请参见WALoptimizers_config
- 详情请参见优化器。shard_number
- 定义集合应该有多少个分片。详情请参见分布式部署章节。on_disk_payload
- 定义有效载荷数据的存储位置。如果设置为true
- 有效载荷将仅存储在磁盘上。对于限制大有效载荷情况下的内存使用可能有用。quantization_config
- 详情请参见量化。strict_mode_config
- 详情请参见严格模式。
可选集合参数的默认参数定义在配置文件中。
自 v1.2.0 起可用
向量全部存储在 RAM 中,以实现快速访问。可以在向量配置中设置 on_disk
参数。如果为 true,所有向量将存储在磁盘上。这将启用内存映射的使用,适用于摄取大量数据。
从另一个集合创建集合
自 v1.0.0 起可用
可以从另一个现有集合初始化一个集合。
这对于使用相同数据集快速实验不同的配置可能很有用。
在新集合中设置向量配置时,请确保向量具有相同的 size
和 distance
函数。如果您使用了之前的示例代码,即 "size": 300
和 "distance": "Cosine"
。
PUT /collections/{collection_name}
{
"vectors": {
"size": 100,
"distance": "Cosine"
},
"init_from": {
"collection": "{from_collection_name}"
}
}
curl -X PUT http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"size": 300,
"distance": "Cosine"
},
"init_from": {
"collection": {from_collection_name}
}
}'
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(size=100, distance=models.Distance.COSINE),
init_from=models.InitFrom(collection="{from_collection_name}"),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: { size: 100, distance: "Cosine" },
init_from: { collection: "{from_collection_name}" },
});
use qdrant_client::Qdrant;
use qdrant_client::qdrant::{CreateCollectionBuilder, Distance, VectorParamsBuilder};
let client = Qdrant::from_url("http://localhost:6334").build()?;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.vectors_config(VectorParamsBuilder::new(100, Distance::Cosine))
.init_from_collection("{from_collection_name}"),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
import io.qdrant.client.grpc.Collections.VectorsConfig;
QdrantClient client =
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client
.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setVectorsConfig(
VectorsConfig.newBuilder()
.setParams(
VectorParams.newBuilder()
.setSize(100)
.setDistance(Distance.Cosine)
.build()))
.setInitFromCollection("{from_collection_name}")
.build())
.get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams { Size = 100, Distance = Distance.Cosine },
initFromCollection: "{from_collection_name}"
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
Size: 100,
Distance: qdrant.Distance_Cosine,
}),
InitFromCollection: qdrant.PtrOf("{from_collection_name}"),
})
包含多个向量的集合
自 v0.10.0 起可用
每个记录可以包含多个向量。此功能允许每个集合有多个向量存储。为了区分同一记录中的向量,创建集合时应为它们定义一个唯一的名称。在此模式下,每个命名向量都有自己的距离和大小。
PUT /collections/{collection_name}
{
"vectors": {
"image": {
"size": 4,
"distance": "Dot"
},
"text": {
"size": 8,
"distance": "Cosine"
}
}
}
curl -X PUT http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"image": {
"size": 4,
"distance": "Dot"
},
"text": {
"size": 8,
"distance": "Cosine"
}
}
}'
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="{collection_name}",
vectors_config={
"image": models.VectorParams(size=4, distance=models.Distance.DOT),
"text": models.VectorParams(size=8, distance=models.Distance.COSINE),
},
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
image: { size: 4, distance: "Dot" },
text: { size: 8, distance: "Cosine" },
},
});
use qdrant_client::Qdrant;
use qdrant_client::qdrant::{
CreateCollectionBuilder, Distance, VectorParamsBuilder, VectorsConfigBuilder,
};
let client = Qdrant::from_url("http://localhost:6334").build()?;
let mut vectors_config = VectorsConfigBuilder::default();
vectors_config
.add_named_vector_params("image", VectorParamsBuilder::new(4, Distance::Dot).build());
vectors_config.add_named_vector_params(
"text",
VectorParamsBuilder::new(8, Distance::Cosine).build(),
);
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}").vectors_config(vectors_config),
)
.await?;
import java.util.Map;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
QdrantClient client =
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client
.createCollectionAsync(
"{collection_name}",
Map.of(
"image", VectorParams.newBuilder().setSize(4).setDistance(Distance.Dot).build(),
"text",
VectorParams.newBuilder().setSize(8).setDistance(Distance.Cosine).build()))
.get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParamsMap
{
Map =
{
["image"] = new VectorParams { Size = 4, Distance = Distance.Dot },
["text"] = new VectorParams { Size = 8, Distance = Distance.Cosine },
}
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfigMap(
map[string]*qdrant.VectorParams{
"image": {
Size: 4,
Distance: qdrant.Distance_Dot,
},
"text": {
Size: 8,
Distance: qdrant.Distance_Cosine,
},
}),
})
在极少数用例中,可以创建一个不包含任何向量存储的集合。
自 v1.1.1 起可用
对于每个命名向量,您可以选择指定hnsw_config
或quantization_config
,以偏离集合配置。这对于在向量级别微调搜索性能很有用。
自 v1.2.0 起可用
向量全部存储在 RAM 中以实现快速访问。对于每个向量,您可以将 on_disk
设置为 true,以便始终将所有向量存储在磁盘上。这将启用内存映射的使用,适用于摄取大量数据。
向量数据类型
自 v1.9.0 起可用
一些嵌入提供商可能以预量化格式提供嵌入。其中一个最著名的例子是Cohere int8 和二进制嵌入。Qdrant 直接支持 uint8 嵌入,您也可以将其与二进制量化结合使用。
要创建一个包含 uint8 嵌入的集合,您可以使用以下配置
PUT /collections/{collection_name}
{
"vectors": {
"size": 1024,
"distance": "Cosine",
"datatype": "uint8"
}
}
curl -X PUT http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"size": 1024,
"distance": "Cosine",
"datatype": "uint8"
}
}'
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="{collection_name}",
vectors_config=models.VectorParams(
size=1024,
distance=models.Distance.COSINE,
datatype=models.Datatype.UINT8,
),
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
vectors: {
image: { size: 1024, distance: "Cosine", datatype: "uint8" },
},
});
use qdrant_client::Qdrant;
use qdrant_client::qdrant::{
CreateCollectionBuilder, Datatype, Distance, VectorParamsBuilder,
};
let client = Qdrant::from_url("http://localhost:6334").build()?;
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}").vectors_config(
VectorParamsBuilder::new(1024, Distance::Cosine).datatype(Datatype::Uint8),
),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.Collections.Datatype;
import io.qdrant.client.grpc.Collections.Distance;
import io.qdrant.client.grpc.Collections.VectorParams;
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client
.createCollectionAsync("{collection_name}",
VectorParams.newBuilder()
.setSize(1024)
.setDistance(Distance.Cosine)
.setDatatype(Datatype.Uint8)
.build())
.get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
vectorsConfig: new VectorParams {
Size = 1024, Distance = Distance.Cosine, Datatype = Datatype.Uint8
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfig(&qdrant.VectorParams{
Size: 1024,
Distance: qdrant.Distance_Cosine,
Datatype: qdrant.Datatype_Uint8.Enum(),
}),
})
数据类型为 uint8
的向量以更紧凑的格式存储,可以节省内存并提高搜索速度,但会牺牲一些精度。如果您选择使用 uint8
数据类型,向量的元素将存储为无符号 8 位整数,取值范围为 0 到 255。
包含稀疏向量的集合
自 v1.7.0 起可用
Qdrant 将稀疏向量作为一等公民支持。
稀疏向量对于文本搜索很有用,其中每个词被表示为一个单独的维度。
集合可以包含稀疏向量作为额外的命名向量,与单个点中的常规密集向量并存。
与密集向量不同,稀疏向量必须命名。此外,稀疏向量和密集向量在同一集合中必须具有不同的名称。
PUT /collections/{collection_name}
{
"sparse_vectors": {
"text": { }
}
}
curl -X PUT http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"sparse_vectors": {
"text": { }
}
}'
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333")
client.create_collection(
collection_name="{collection_name}",
vectors_config={},
sparse_vectors_config={
"text": models.SparseVectorParams(),
},
)
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.createCollection("{collection_name}", {
sparse_vectors: {
text: { },
},
});
use qdrant_client::Qdrant;
use qdrant_client::qdrant::{
CreateCollectionBuilder, SparseVectorParamsBuilder, SparseVectorsConfigBuilder,
};
let client = Qdrant::from_url("http://localhost:6334").build()?;
let mut sparse_vector_config = SparseVectorsConfigBuilder::default();
sparse_vector_config.add_named_vector_params("text", SparseVectorParamsBuilder::default());
client
.create_collection(
CreateCollectionBuilder::new("{collection_name}")
.sparse_vectors_config(sparse_vector_config),
)
.await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import io.qdrant.client.grpc.Collections.CreateCollection;
import io.qdrant.client.grpc.Collections.SparseVectorConfig;
import io.qdrant.client.grpc.Collections.SparseVectorParams;
QdrantClient client =
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client
.createCollectionAsync(
CreateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setSparseVectorsConfig(
SparseVectorConfig.newBuilder()
.putMap("text", SparseVectorParams.getDefaultInstance()))
.build())
.get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.CreateCollectionAsync(
collectionName: "{collection_name}",
sparseVectorsConfig: ("text", new SparseVectorParams())
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.CreateCollection(context.Background(), &qdrant.CreateCollection{
CollectionName: "{collection_name}",
SparseVectorsConfig: qdrant.NewSparseVectorsConfig(
map[string]*qdrant.SparseVectorParams{
"text": {},
}),
})
除了唯一的名称之外,稀疏向量没有必需的配置参数。
稀疏向量的距离函数始终是 Dot
,无需指定。
然而,存在可选参数来调整底层的稀疏向量索引。
检查集合是否存在
自 v1.8.0 起可用
GET http://localhost:6333/collections/{collection_name}/exists
curl -X GET http://localhost:6333/collections/{collection_name}/exists
client.collection_exists(collection_name="{collection_name}")
client.collectionExists("{collection_name}");
client.collection_exists("{collection_name}").await?;
client.collectionExistsAsync("{collection_name}").get();
await client.CollectionExistsAsync("{collection_name}");
import "context"
client.CollectionExists(context.Background(), "my_collection")
删除集合
DELETE http://localhost:6333/collections/{collection_name}
curl -X DELETE http://localhost:6333/collections/{collection_name}
client.delete_collection(collection_name="{collection_name}")
client.deleteCollection("{collection_name}");
client.delete_collection("{collection_name}").await?;
client.deleteCollectionAsync("{collection_name}").get();
await client.DeleteCollectionAsync("{collection_name}");
import "context"
client.DeleteCollection(context.Background(), "{collection_name}")
更新集合参数
动态参数更新可能很有用,例如,为了更有效地初始加载向量。例如,您可以在上传过程中禁用索引,并在上传完成后立即启用。这样,您就不会浪费额外的计算资源用于重建索引。
以下命令为存储向量超过 10000 kB 的段启用索引
PATCH /collections/{collection_name}
{
"optimizers_config": {
"indexing_threshold": 10000
}
}
curl -X PATCH http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"optimizers_config": {
"indexing_threshold": 10000
}
}'
client.update_collection(
collection_name="{collection_name}",
optimizers_config=models.OptimizersConfigDiff(indexing_threshold=10000),
)
client.updateCollection("{collection_name}", {
optimizers_config: {
indexing_threshold: 10000,
},
});
use qdrant_client::qdrant::{OptimizersConfigDiffBuilder, UpdateCollectionBuilder};
client
.update_collection(
UpdateCollectionBuilder::new("{collection_name}").optimizers_config(
OptimizersConfigDiffBuilder::default().indexing_threshold(10000),
),
)
.await?;
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
import io.qdrant.client.grpc.Collections.UpdateCollection;
client.updateCollectionAsync(
UpdateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setOptimizersConfig(
OptimizersConfigDiff.newBuilder().setIndexingThreshold(10000).build())
.build());
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.UpdateCollectionAsync(
collectionName: "{collection_name}",
optimizersConfig: new OptimizersConfigDiff { IndexingThreshold = 10000 }
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.UpdateCollection(context.Background(), &qdrant.UpdateCollection{
CollectionName: "{collection_name}",
OptimizersConfig: &qdrant.OptimizersConfigDiff{
IndexingThreshold: qdrant.PtrOf(uint64(10000)),
},
})
以下参数可以更新
optimizers_config
- 详情请参见优化器。hnsw_config
- 详情请参见索引。quantization_config
- 详情请参见量化。vectors_config
- 特定于向量的配置,包括单独的hnsw_config
、quantization_config
和on_disk
设置。params
- 其他集合参数,包括write_consistency_factor
和on_disk_payload
。strict_mode_config
- 详情请参见严格模式。
完整的 API 规范可在模式定义中找到。
对此端点的调用可能会阻塞,因为它会等待现有的优化器完成。不建议在生产数据库中使用此功能,因为它可能因重建索引而引入巨大的开销。
更新向量参数
自 v1.4.0 起可用
Qdrant 1.4 增加了对运行时更新更多集合参数的支持。现在可以在不重新创建集合的情况下更改 HNSW 索引、量化和磁盘配置。段(及其索引和量化数据)将在后台自动重建以匹配更新的参数。
对于没有命名向量的集合,要将向量数据存储到磁盘,请使用 ""
作为名称
PATCH /collections/{collection_name}
{
"vectors": {
"": {
"on_disk": true
}
}
}
curl -X PATCH http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"": {
"on_disk": true
}
}
}'
对于有命名向量的集合,要将向量数据存储到磁盘
注意:要创建向量名称,请遵循我们点中的程序。
PATCH /collections/{collection_name}
{
"vectors": {
"my_vector": {
"on_disk": true
}
}
}
curl -X PATCH http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"my_vector": {
"on_disk": true
}
}
}'
在下面的示例中,更新了 HNSW 索引和量化参数,包括整个集合以及专门针对 my_vector
的参数。
PATCH /collections/{collection_name}
{
"vectors": {
"my_vector": {
"hnsw_config": {
"m": 32,
"ef_construct": 123
},
"quantization_config": {
"product": {
"compression": "x32",
"always_ram": true
}
},
"on_disk": true
}
},
"hnsw_config": {
"ef_construct": 123
},
"quantization_config": {
"scalar": {
"type": "int8",
"quantile": 0.8,
"always_ram": false
}
}
}
curl -X PATCH http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"vectors": {
"my_vector": {
"hnsw_config": {
"m": 32,
"ef_construct": 123
},
"quantization_config": {
"product": {
"compression": "x32",
"always_ram": true
}
},
"on_disk": true
}
},
"hnsw_config": {
"ef_construct": 123
},
"quantization_config": {
"scalar": {
"type": "int8",
"quantile": 0.8,
"always_ram": false
}
}
}'
client.update_collection(
collection_name="{collection_name}",
vectors_config={
"my_vector": models.VectorParamsDiff(
hnsw_config=models.HnswConfigDiff(
m=32,
ef_construct=123,
),
quantization_config=models.ProductQuantization(
product=models.ProductQuantizationConfig(
compression=models.CompressionRatio.X32,
always_ram=True,
),
),
on_disk=True,
),
},
hnsw_config=models.HnswConfigDiff(
ef_construct=123,
),
quantization_config=models.ScalarQuantization(
scalar=models.ScalarQuantizationConfig(
type=models.ScalarType.INT8,
quantile=0.8,
always_ram=False,
),
),
)
client.updateCollection("{collection_name}", {
vectors: {
my_vector: {
hnsw_config: {
m: 32,
ef_construct: 123,
},
quantization_config: {
product: {
compression: "x32",
always_ram: true,
},
},
on_disk: true,
},
},
hnsw_config: {
ef_construct: 123,
},
quantization_config: {
scalar: {
type: "int8",
quantile: 0.8,
always_ram: true,
},
},
});
use std::collections::HashMap;
use qdrant_client::qdrant::{
quantization_config_diff::Quantization, vectors_config_diff::Config, HnswConfigDiffBuilder,
QuantizationType, ScalarQuantizationBuilder, UpdateCollectionBuilder, VectorParamsDiffBuilder,
VectorParamsDiffMap,
};
client
.update_collection(
UpdateCollectionBuilder::new("{collection_name}")
.hnsw_config(HnswConfigDiffBuilder::default().ef_construct(123))
.vectors_config(Config::ParamsMap(VectorParamsDiffMap {
map: HashMap::from([(
("my_vector".into()),
VectorParamsDiffBuilder::default()
.hnsw_config(HnswConfigDiffBuilder::default().m(32).ef_construct(123))
.build(),
)]),
}))
.quantization_config(Quantization::Scalar(
ScalarQuantizationBuilder::default()
.r#type(QuantizationType::Int8.into())
.quantile(0.8)
.always_ram(true)
.build(),
)),
)
.await?;
import io.qdrant.client.grpc.Collections.HnswConfigDiff;
import io.qdrant.client.grpc.Collections.QuantizationConfigDiff;
import io.qdrant.client.grpc.Collections.QuantizationType;
import io.qdrant.client.grpc.Collections.ScalarQuantization;
import io.qdrant.client.grpc.Collections.UpdateCollection;
import io.qdrant.client.grpc.Collections.VectorParamsDiff;
import io.qdrant.client.grpc.Collections.VectorParamsDiffMap;
import io.qdrant.client.grpc.Collections.VectorsConfigDiff;
client
.updateCollectionAsync(
UpdateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setHnswConfig(HnswConfigDiff.newBuilder().setEfConstruct(123).build())
.setVectorsConfig(
VectorsConfigDiff.newBuilder()
.setParamsMap(
VectorParamsDiffMap.newBuilder()
.putMap(
"my_vector",
VectorParamsDiff.newBuilder()
.setHnswConfig(
HnswConfigDiff.newBuilder()
.setM(3)
.setEfConstruct(123)
.build())
.build())))
.setQuantizationConfig(
QuantizationConfigDiff.newBuilder()
.setScalar(
ScalarQuantization.newBuilder()
.setType(QuantizationType.Int8)
.setQuantile(0.8f)
.setAlwaysRam(true)
.build()))
.build())
.get();
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.UpdateCollectionAsync(
collectionName: "{collection_name}",
hnswConfig: new HnswConfigDiff { EfConstruct = 123 },
vectorsConfig: new VectorParamsDiffMap
{
Map =
{
{
"my_vector",
new VectorParamsDiff
{
HnswConfig = new HnswConfigDiff { M = 3, EfConstruct = 123 }
}
}
}
},
quantizationConfig: new QuantizationConfigDiff
{
Scalar = new ScalarQuantization
{
Type = QuantizationType.Int8,
Quantile = 0.8f,
AlwaysRam = true
}
}
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.UpdateCollection(context.Background(), &qdrant.UpdateCollection{
CollectionName: "{collection_name}",
VectorsConfig: qdrant.NewVectorsConfigDiffMap(
map[string]*qdrant.VectorParamsDiff{
"my_vector": {
HnswConfig: &qdrant.HnswConfigDiff{
M: qdrant.PtrOf(uint64(3)),
EfConstruct: qdrant.PtrOf(uint64(123)),
},
},
}),
QuantizationConfig: qdrant.NewQuantizationDiffScalar(
&qdrant.ScalarQuantization{
Type: qdrant.QuantizationType_Int8,
Quantile: qdrant.PtrOf(float32(0.8)),
AlwaysRam: qdrant.PtrOf(true),
}),
})
集合信息
Qdrant 允许确定现有集合的配置参数,以便更好地理解点的分布和索引方式。
GET /collections/{collection_name}
curl -X GET http://localhost:6333/collections/{collection_name}
client.get_collection(collection_name="{collection_name}")
client.getCollection("{collection_name}");
client.collection_info("{collection_name}").await?;
client.getCollectionInfoAsync("{collection_name}").get();
await client.GetCollectionInfoAsync("{collection_name}");
import "context"
client.GetCollectionInfo(context.Background(), "{collection_name}")
预期结果
{
"result": {
"status": "green",
"optimizer_status": "ok",
"vectors_count": 1068786,
"indexed_vectors_count": 1024232,
"points_count": 1068786,
"segments_count": 31,
"config": {
"params": {
"vectors": {
"size": 384,
"distance": "Cosine"
},
"shard_number": 1,
"replication_factor": 1,
"write_consistency_factor": 1,
"on_disk_payload": false
},
"hnsw_config": {
"m": 16,
"ef_construct": 100,
"full_scan_threshold": 10000,
"max_indexing_threads": 0
},
"optimizer_config": {
"deleted_threshold": 0.2,
"vacuum_min_vector_number": 1000,
"default_segment_number": 0,
"max_segment_size": null,
"memmap_threshold": null,
"indexing_threshold": 20000,
"flush_interval_sec": 5,
"max_optimization_threads": 1
},
"wal_config": {
"wal_capacity_mb": 32,
"wal_segments_ahead": 0
}
},
"payload_schema": {}
},
"status": "ok",
"time": 0.00010143
}
如果您将向量插入集合,status
字段在优化期间可能会变为 yellow
。所有点成功处理后,它将变为 green
。
可能的状态颜色如下
- 🟢
green
: 集合已就绪 - 🟡
yellow
: 集合正在优化 - ⚫
grey
: 集合待优化(帮助) - 🔴
red
: 引擎发生无法恢复的错误
灰色集合状态
自 v1.9.0 起可用
集合可能显示灰色 ⚫ 状态或优化状态显示为“优化待处理,等待更新操作”。这种情况通常是由于在优化进行期间重新启动 Qdrant 实例引起的。
这意味着集合有待处理的优化,但已暂停。您必须发送任何更新操作来再次触发并启动优化。
例如
PATCH /collections/{collection_name}
{
"optimizers_config": {}
}
curl -X PATCH http://localhost:6333/collections/{collection_name} \
-H 'Content-Type: application/json' \
--data-raw '{
"optimizers_config": {}
}'
client.update_collection(
collection_name="{collection_name}",
optimizer_config=models.OptimizersConfigDiff(),
)
client.updateCollection("{collection_name}", {
optimizers_config: {},
});
use qdrant_client::qdrant::{OptimizersConfigDiffBuilder, UpdateCollectionBuilder};
client
.update_collection(
UpdateCollectionBuilder::new("{collection_name}")
.optimizers_config(OptimizersConfigDiffBuilder::default()),
)
.await?;
import io.qdrant.client.grpc.Collections.OptimizersConfigDiff;
import io.qdrant.client.grpc.Collections.UpdateCollection;
client.updateCollectionAsync(
UpdateCollection.newBuilder()
.setCollectionName("{collection_name}")
.setOptimizersConfig(
OptimizersConfigDiff.getDefaultInstance())
.build());
using Qdrant.Client;
using Qdrant.Client.Grpc;
var client = new QdrantClient("localhost", 6334);
await client.UpdateCollectionAsync(
collectionName: "{collection_name}",
optimizersConfig: new OptimizersConfigDiff { }
);
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.UpdateCollection(context.Background(), &qdrant.UpdateCollection{
CollectionName: "{collection_name}",
OptimizersConfig: &qdrant.OptimizersConfigDiff{},
})
或者,您可以使用Qdrant Web UI中的 Trigger Optimizers
按钮。该按钮显示在集合信息页面中灰色集合状态旁边。
大约的点和向量计数
您可能对计数属性感兴趣
points_count
- 集合中存储的对象(向量及其有效载荷)总数vectors_count
- 集合中的向量总数,如果您每个点有多个向量,则此属性有用indexed_vectors_count
- 存储在 HNSW 或稀疏索引中的向量总数。Qdrant 并不会将所有向量都存储在索引中,只有当给定的配置可能创建索引段时才会存储。
以上计数不精确,应视为近似值。根据您使用 Qdrant 的方式,这些计数可能与您的预期大相径庭。因此,不要依赖它们是很重要的。
更具体地说,这些数字代表 Qdrant 内部存储中点和向量的计数。在内部,Qdrant 可能会作为自动优化的一部分临时复制点。它可能会保留更改或删除的点一段时间。并且可能会延迟新点的索引。所有这些都是出于优化原因。
因此,您所做的更新不会直接反映在这些数字中。如果您看到点计数差异很大,一旦新一轮的自动优化完成,这种情况很可能会自行解决。
澄清一下:这些数字不代表您插入的点或向量的确切数量,也不代表您可以查询的可区分的点或向量的确切数量。如果您想知道确切的计数,请参阅计数 API。
注意:这些数字可能会在未来的 Qdrant 版本中移除。
在 HNSW 中索引向量
在某些情况下,您可能会惊讶于 indexed_vectors_count
的值低于 vectors_count
。这是一种预期行为,取决于优化器配置。如果未索引向量的大小高于 indexing_threshold
(以 kB 为单位)的值,则会构建一个新的索引段。如果您的集合非常小或向量的维度较低,则可能不会创建 HNSW 段,indexed_vectors_count
可能等于 0
。
可以通过更新集合参数来减少现有集合的 indexing_threshold
。
集合别名
在生产环境中,有时需要无缝切换不同版本的向量。例如,在升级到新版本的神经网络时。
在这些情况下,无法停止服务并使用新向量重建集合。别名是现有集合的附加名称。对集合的所有查询都可以通过使用别名而不是集合名称来以相同的方式完成。
因此,可以在后台构建第二个集合,然后将别名从旧集合切换到新集合。由于所有别名更改都是原子发生的,因此在切换过程中不会影响任何并发请求。
创建别名
POST /collections/aliases
{
"actions": [
{
"create_alias": {
"collection_name": "example_collection",
"alias_name": "production_collection"
}
}
]
}
curl -X POST http://localhost:6333/collections/aliases \
-H 'Content-Type: application/json' \
--data-raw '{
"actions": [
{
"create_alias": {
"collection_name": "example_collection",
"alias_name": "production_collection"
}
}
]
}'
client.update_collection_aliases(
change_aliases_operations=[
models.CreateAliasOperation(
create_alias=models.CreateAlias(
collection_name="example_collection", alias_name="production_collection"
)
)
]
)
client.updateCollectionAliases({
actions: [
{
create_alias: {
collection_name: "example_collection",
alias_name: "production_collection",
},
},
],
});
use qdrant_client::qdrant::CreateAliasBuilder;
client
.create_alias(CreateAliasBuilder::new(
"example_collection",
"production_collection",
))
.await?;
client.createAliasAsync("production_collection", "example_collection").get();
await client.CreateAliasAsync(aliasName: "production_collection", collectionName: "example_collection");
import "context"
client.CreateAlias(context.Background(), "production_collection", "example_collection")
删除别名
POST /collections/aliases
{
"actions": [
{
"delete_alias": {
"alias_name": "production_collection"
}
}
]
}
curl -X POST http://localhost:6333/collections/aliases \
-H 'Content-Type: application/json' \
--data-raw '{
"actions": [
{
"delete_alias": {
"alias_name": "production_collection"
}
}
]
}'
client.update_collection_aliases(
change_aliases_operations=[
models.DeleteAliasOperation(
delete_alias=models.DeleteAlias(alias_name="production_collection")
),
]
)
client.updateCollectionAliases({
actions: [
{
delete_alias: {
alias_name: "production_collection",
},
},
],
});
client.delete_alias("production_collection").await?;
client.deleteAliasAsync("production_collection").get();
await client.DeleteAliasAsync("production_collection");
import "context"
client.DeleteAlias(context.Background(), "production_collection")
切换集合
多个别名操作以原子方式执行。例如,您可以使用以下命令切换底层集合
POST /collections/aliases
{
"actions": [
{
"delete_alias": {
"alias_name": "production_collection"
}
},
{
"create_alias": {
"collection_name": "example_collection",
"alias_name": "production_collection"
}
}
]
}
curl -X POST http://localhost:6333/collections/aliases \
-H 'Content-Type: application/json' \
--data-raw '{
"actions": [
{
"delete_alias": {
"alias_name": "production_collection"
}
},
{
"create_alias": {
"collection_name": "example_collection",
"alias_name": "production_collection"
}
}
]
}'
client.update_collection_aliases(
change_aliases_operations=[
models.DeleteAliasOperation(
delete_alias=models.DeleteAlias(alias_name="production_collection")
),
models.CreateAliasOperation(
create_alias=models.CreateAlias(
collection_name="example_collection", alias_name="production_collection"
)
),
]
)
client.updateCollectionAliases({
actions: [
{
delete_alias: {
alias_name: "production_collection",
},
},
{
create_alias: {
collection_name: "example_collection",
alias_name: "production_collection",
},
},
],
});
use qdrant_client::qdrant::CreateAliasBuilder;
client.delete_alias("production_collection").await?;
client
.create_alias(CreateAliasBuilder::new(
"example_collection",
"production_collection",
))
.await?;
client.deleteAliasAsync("production_collection").get();
client.createAliasAsync("production_collection", "example_collection").get();
await client.DeleteAliasAsync("production_collection");
await client.CreateAliasAsync(aliasName: "production_collection", collectionName: "example_collection");
import "context"
client.DeleteAlias(context.Background(), "production_collection")
client.CreateAlias(context.Background(), "production_collection", "example_collection")
列出集合别名
GET /collections/{collection_name}/aliases
curl -X GET http://localhost:6333/collections/{collection_name}/aliases
from qdrant_client import QdrantClient
client = QdrantClient(url="http://localhost:6333")
client.get_collection_aliases(collection_name="{collection_name}")
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.getCollectionAliases("{collection_name}");
use qdrant_client::Qdrant;
let client = Qdrant::from_url("http://localhost:6334").build()?;
client.list_collection_aliases("{collection_name}").await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
QdrantClient client =
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client.listCollectionAliasesAsync("{collection_name}").get();
using Qdrant.Client;
var client = new QdrantClient("localhost", 6334);
await client.ListCollectionAliasesAsync("{collection_name}");
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.ListCollectionAliases(context.Background(), "{collection_name}")
列出所有别名
GET /aliases
curl -X GET http://localhost:6333/aliases
from qdrant_client import QdrantClient
client = QdrantClient(url="http://localhost:6333")
client.get_aliases()
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.getAliases();
use qdrant_client::Qdrant;
let client = Qdrant::from_url("http://localhost:6334").build()?;
client.list_aliases().await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
QdrantClient client =
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client.listAliasesAsync().get();
using Qdrant.Client;
var client = new QdrantClient("localhost", 6334);
await client.ListAliasesAsync();
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.ListAliases(context.Background())
列出所有集合
GET /collections
curl -X GET http://localhost:6333/collections
from qdrant_client import QdrantClient
client = QdrantClient(url="http://localhost:6333")
client.get_collections()
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ host: "localhost", port: 6333 });
client.getCollections();
use qdrant_client::Qdrant;
let client = Qdrant::from_url("http://localhost:6334").build()?;
client.list_collections().await?;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
QdrantClient client =
new QdrantClient(QdrantGrpcClient.newBuilder("localhost", 6334, false).build());
client.listCollectionsAsync().get();
using Qdrant.Client;
var client = new QdrantClient("localhost", 6334);
await client.ListCollectionsAsync();
import (
"context"
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "localhost",
Port: 6334,
})
client.ListCollections(context.Background())