Qdrant 向量数据库使用指南
1. Qdrant 简介
Qdrant 是一个高性能、开源的向量数据库,专门为处理和搜索大规模向量数据而设计。它提供了实时的向量相似度搜索功能,支持多种距离度量(如余弦相似度、欧几里得距离等),并具有强大的过滤和查询能力。Qdrant 特别适合用于构建语义搜索、推荐系统、图像识别和自然语言处理等应用。
2. 安装和启动 Qdrant
2.1 使用 Docker 安装(推荐)
# 拉取 Qdrant 镜像
docker pull qdrant/qdrant
# 启动 Qdrant 容器
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
2.2 从源代码安装
# 克隆 Qdrant 仓库
git clone https://github.com/qdrant/qdrant.git
# 构建并运行 Qdrant
cd qdrant
cargo run --release
2.3 验证 Qdrant 是否正常运行
# 访问 Qdrant 健康检查端点
curl -X GET http://localhost:6333/healthz
如果返回 {"status":"ok"},说明 Qdrant 已成功启动。
2.4 访问 Qdrant Web UI
Qdrant 提供了一个内置的 Web 界面,用于可视化和管理数据。
访问地址:
打开浏览器访问 http://localhost:6333/dashboard
Web UI 功能:
- 查看所有集合的基本信息和统计数据
- 查询向量数据和可视化查询结果
- 管理集合配置和索引
- 数据导入/导出功能
- 查询性能分析和优化建议
3. 基础配置
3.1 配置文件
Qdrant 使用 YAML 文件进行配置,默认路径为 /qdrant/config/production.yaml。常见配置项包括:
service:
grpc_port: 6334
http_port: 6333
host: 0.0.0.0
storage:
storage_path: ./storage
snapshot_dir: ./snapshots
3.2 环境变量配置
# 设置 Qdrant 数据存储路径
export QDRANT_STORAGE_PATH=/path/to/storage
# 设置 Qdrant 监听地址
export QDRANT_HOST=0.0.0.0
# 启动 Qdrant
qdrant
4. 使用 Python 客户端
4.1 安装 Python 客户端
pip install qdrant-client
4.2 基本操作
from qdrant_client import QdrantClient
from qdrant_client.models import VectorParams, Distance, PointStruct
# 连接到 Qdrant
client = QdrantClient(host="localhost", port=6333)
# 创建集合
collection_name = "test_collection"
client.recreate_collection(
collection_name=collection_name,
vectors_config=VectorParams(size=4, distance=Distance.COSINE)
)
# 插入数据
points = [
PointStruct(id=1, vector=[0.05, 0.61, 0.76, 0.74], payload={"city": "Berlin"}),
PointStruct(id=2, vector=[0.19, 0.81, 0.75, 0.11], payload={"city": "London"}),
PointStruct(id=3, vector=[0.36, 0.55, 0.47, 0.94], payload={"city": "Moscow"}),
PointStruct(id=4, vector=[0.18, 0.01, 0.85, 0.80], payload={"city": "New York"}),
PointStruct(id=5, vector=[0.24, 0.18, 0.22, 0.44], payload={"city": "Beijing"}),
PointStruct(id=6, vector=[0.35, 0.08, 0.11, 0.44], payload={"city": "Mumbai"}),
]
client.upsert(collection_name=collection_name, points=points)
# 搜索数据
search_result = client.search(
collection_name=collection_name,
query=[0.2, 0.1, 0.9, 0.7],
limit=3
)
print("搜索结果:")
for point in search_result:
print(f"ID: {point.id}, 分数: {point.score}, 城市: {point.payload['city']}")
# 删除集合
client.delete_collection(collection_name=collection_name)
5. 使用异步 Python 客户端
5.1 异步操作示例
import asyncio
from qdrant_client import AsyncQdrantClient
from qdrant_client.models import VectorParams, Distance, PointStruct
async def main():
client = AsyncQdrantClient(host="localhost", port=6333)
# 创建集合
collection_name = "async_collection"
await client.recreate_collection(
collection_name=collection_name,
vectors_config=VectorParams(size=4, distance=Distance.COSINE)
)
# 插入数据
points = [
PointStruct(id=1, vector=[0.05, 0.61, 0.76, 0.74], payload={"city": "Berlin"}),
PointStruct(id=2, vector=[0.19, 0.81, 0.75, 0.11], payload={"city": "London"}),
PointStruct(id=3, vector=[0.36, 0.55, 0.47, 0.94], payload={"city": "Moscow"}),
]
await client.upsert(collection_name=collection_name, points=points)
# 搜索数据
search_result = await client.search(
collection_name=collection_name,
query=[0.2, 0.1, 0.9, 0.7],
limit=2
)
print("异步搜索结果:")
for point in search_result:
print(f"ID: {point.id}, 分数: {point.score}, 城市: {point.payload['city']}")
# 删除集合
await client.delete_collection(collection_name=collection_name)
asyncio.run(main())
6. 高级功能
6.1 过滤搜索
search_result = client.search(
collection_name=collection_name,
query=[0.2, 0.1, 0.9, 0.7],
limit=3,
query_filter={
"must": [
{
"key": "city",
"match": {
"text": {
"query": "London",
"boost": 2.0
}
}
}
]
}
)
6.2 分页搜索
search_result = client.scroll(
collection_name=collection_name,
offset=0,
limit=10,
scroll_filter={
"must": [
{
"key": "city",
"match": {
"keyword": "Berlin"
}
}
]
}
)
6.3 更新和删除数据
# 更新数据
updated_point = PointStruct(id=1, vector=[0.1, 0.2, 0.3, 0.4], payload={"city": "New Berlin"})
client.upsert(collection_name=collection_name, points=[updated_point])
# 删除数据
client.delete(collection_name=collection_name, points_selector={"ids": [1]})
6.4 集合操作
# 获取集合信息
collection_info = client.get_collection(collection_name=collection_name)
print(f"集合名称: {collection_info.name}")
print(f"向量维度: {collection_info.config.params.vectors.size}")
print(f"距离度量: {collection_info.config.params.vectors.distance}")
# 获取集合统计信息
collection_stats = client.get_collection_stats(collection_name=collection_name)
print(f"点数量: {collection_stats.points_count}")
print(f"向量数量: {collection_stats.vectors_count}")
# 优化集合
client.optimize_collection(collection_name=collection_name)
7. 性能优化
7.1 配置优化
# 调整搜索参数
search:
default_limit: 10
score_threshold: 0.5
radius: 0.5
# 调整存储参数
storage:
optimize_on_disk_threshold: 0.5
preload_collection_names: ["collection1", "collection2"]
7.2 查询优化
search_result = client.search(
collection_name=collection_name,
query=[0.2, 0.1, 0.9, 0.7],
limit=10,
score_threshold=0.5,
radius=0.8,
with_payload=False, # 不返回 payload 以提高速度
with_vectors=False # 不返回向量以提高速度
)
7.3 批量操作
# 批量插入
large_points = [
PointStruct(id=i, vector=[0.1 * i, 0.2 * i, 0.3 * i, 0.4 * i], payload={"value": i})
for i in range(1000)
]
client.upsert(collection_name=collection_name, points=large_points)
# 批量删除
client.delete(collection_name=collection_name, points_selector={"ids": list(range(500))})
8. 与其他工具集成
8.1 与 Hugging Face 集成
from transformers import AutoTokenizer, AutoModel
import torch
# 加载模型
tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
model = AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
# 编码文本
text = "Hello, world!"
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
with torch.no_grad():
outputs = model(**inputs)
vector = outputs.last_hidden_state.mean(dim=1).squeeze().tolist()
# 存储到 Qdrant
point = PointStruct(id=1, vector=vector, payload={"text": text})
client.upsert(collection_name=collection_name, points=[point])
8.2 与 Flask 集成
from flask import Flask, request, jsonify
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct
app = Flask(__name__)
client = QdrantClient(host="localhost", port=6333)
@app.route("/search", methods=["POST"])
def search():
data = request.get_json()
query_vector = data["query_vector"]
search_result = client.search(
collection_name="text_embeddings",
query=query_vector,
limit=10
)
results = []
for point in search_result:
results.append({
"id": point.id,
"score": point.score,
"text": point.payload["text"]
})
return jsonify(results)
if __name__ == "__main__":
app.run()
9. 故障排除
9.1 常见错误和解决方案
错误:连接超时
原因:Qdrant 服务未启动或网络连接问题
解决方案:
- 检查 Qdrant 服务是否正在运行
- 检查防火墙设置
- 确认主机名和端口是否正确
错误:集合不存在
原因:集合已被删除或尚未创建
解决方案:
- 检查集合名称是否正确
- 确认集合是否已创建
- 使用
create_collection或recreate_collection方法创建集合
错误:向量维度不匹配
原因:插入的向量维度与集合配置不匹配
解决方案:
- 检查插入向量的维度
- 确认集合配置的向量维度
- 重新创建集合或调整向量维度
9.2 日志和监控
# 启用调试日志
client = QdrantClient(
host="localhost",
port=6333,
grpc_port=6334,
timeout=10.0,
log_level="DEBUG"
)
# 获取日志信息
import logging
logging.basicConfig(level=logging.DEBUG)
10. 总结
Qdrant 是一个功能强大且易于使用的向量数据库,具有良好的性能和可扩展性。它支持多种编程语言和集成方式,适合各种向量数据存储和搜索场景。
通过合理的配置和优化,Qdrant 可以处理大规模向量数据,并提供快速、准确的搜索结果。如果您正在构建与向量相似度搜索相关的应用,Qdrant 是一个值得考虑的选择。
作者:Work Hard Work Smart
出处:http://www.cnblogs.com/linlf03/
欢迎任何形式的转载,未经作者同意,请保留此段声明!
浙公网安备 33010602011771号