共计 2714 个字符,预计需要花费 7 分钟才能阅读完成。
背景与痛点:为什么需要向量搜索?
传统的关键词搜索(如数据库的 LIKE 操作或全文检索)存在明显的局限性:

- 语义鸿沟 :无法理解查询意图。例如搜索 ” 苹果 ”,可能返回水果或手机品牌,但无法区分上下文。
- 依赖精确匹配 :拼写错误、同义词(如 ” 自行车 ” 和 ” 单车 ”)会导致漏检。
- 多模态支持弱 :难以直接处理图片、音频等非结构化数据的相似性搜索。
向量搜索通过将数据转换为高维向量(通常由 NLP 或 CV 模型生成),计算向量间的距离(如余弦相似度)实现语义级搜索。例如:
# 传统 SQL 搜索(局限性示例)SELECT * FROM products WHERE name LIKE '% 苹果 %';
# 向量搜索逻辑(伪代码)query_vector = model.encode("红色水果")
results = find_vectors_closest_to(query_vector)
ChromaDB 简介:轻量级向量数据库
相比 Faiss(专注性能,无原生存储)、Milvus(功能全但部署复杂),ChromaDB 的核心优势:
- 开箱即用 :Python 优先 API,
pip install chromadb即可开始使用 - 内置持久化 :无需额外配置即可保存数据到磁盘
- 多模态友好 :支持文本、图像等多种向量类型
| 特性 | ChromaDB | Faiss | Milvus |
|---|---|---|---|
| 安装复杂度 | ⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| 持久化 | ✅ | ❌ | ✅ |
| 分布式支持 | ❌ | ❌ | ✅ |
实战步骤:构建智能搜索系统
1. 环境准备
pip install chromadb sentence-transformers # 安装核心库
2. 初始化客户端与集合
import chromadb
from sentence_transformers import SentenceTransformer
# 初始化模型(用于生成文本向量)encoder = SentenceTransformer('paraphrase-MiniLM-L6-v2')
# 创建或加载数据库
client = chromadb.PersistentClient(path="./chroma_db")
collection = client.get_or_create_collection("products")
3. 插入向量数据
# 示例商品数据
products = ["iPhone 13", "红富士苹果", "MacBook Pro", "新鲜香蕉"]
# 生成向量并插入
vectors = encoder.encode(products).tolist() # 转换为 list
collection.add(
documents=products,
embeddings=vectors,
ids=[f"id_{i}" for i in range(len(products))]
)
4. 语义搜索实现
def semantic_search(query: str, top_k: int = 3):
query_vector = encoder.encode(query).tolist()
results = collection.query(query_embeddings=[query_vector],
n_results=top_k
)
return results["documents"][0]
# 测试:搜索 "手机"(应返回 iPhone 相关结果)print(semantic_search("手机")) # 输出:['iPhone 13', ...]
性能优化技巧
- 批量操作 :避免单条插入,使用
add方法的批量参数
# 批量插入 10 万条数据的效率比单条循环高 50 倍以上
collection.add(documents=batch_texts, embeddings=batch_vectors)
- 索引策略 :默认使用 HNSW 算法,调整参数平衡精度 / 速度
collection = client.create_collection(
name="optimized",
metadata={"hnsw:space": "cosine", "hnsw:M": 32} # 加大 M 提升召回率
)
- 过滤加速 :结合 metadata 进行预过滤
# 先按类别过滤,再向量搜索
results = collection.query(query_embeddings=[query_vector],
where={"category": "electronics"}, # 元数据过滤
n_results=10
)
生产环境注意事项
- 持久化备份 :虽然 ChromaDB 自动保存数据,但仍需定期备份
chroma_db目录 - 并发控制 :写入时使用锁机制(如文件锁或分布式锁)
- 错误恢复 :捕获
chromadb.errors并实现重试逻辑
from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
def safe_add_documents(docs):
try:
collection.add(documents=docs)
except chromadb.errors.ChromaError as e:
log_error(e)
扩展思考:结合 NLP 模型增强搜索
- 多语言支持 :切换为多语言编码模型(如
paraphrase-multilingual-MiniLM-L12-v2) - 混合搜索 :结合关键词与向量分数进行加权排序
- 动态调优 :根据用户点击反馈微调向量模型(需要记录查询日志)
# 混合搜索示例
def hybrid_search(query, keyword_weight=0.3):
# 向量搜索得分
vector_results = collection.query(query_embeddings=[encoder.encode(query)], include=["distances"])
# 关键词匹配得分(需提前创建倒排索引)keyword_scores = compute_keyword_match_scores(query)
# 加权合并
combined_scores = combine_scores(vector_results["distances"], keyword_scores, keyword_weight)
return sort_by_score(combined_scores)
总结
通过 ChromaDB,我们用不到 50 行代码实现了语义搜索系统。相比搭建传统搜索引擎(如 Elasticsearch),向量方案在语义理解上具有天然优势。下一步可以尝试:
- 接入开源大模型(如 Llama 3)生成更优质的向量
- 实现基于用户行为的动态排序(如点击率加权)
- 探索跨模态搜索(文本搜图片 / 视频)
完整代码示例已上传 GitHub(虚构链接),欢迎在评论区交流实际应用中的优化技巧。
正文完
发表至: 未分类
近一天内
