Chroma核心API与快速上手指南
Chroma作为AI原生的开源嵌入数据库,其核心API设计极其简洁高效,仅包含四个主要函数:create_collection、add、query和get。这种设计哲学使得开发者能够快速上手,同时保持强大的功能扩展性。本文将深入解析这四大核心API的功能特性、参数细节和使用场景,涵盖本地内存模式与持久化存储配置、集合创建与文档管理操作、以及相似性搜索与查询功能实践。
Chroma四大核心API函数详解
Chroma作为AI原生的开源嵌入数据库,其核心API设计极其简洁高效,仅包含四个主要函数:create_collection、add、query和get。这种设计哲学使得开发者能够快速上手,同时保持强大的功能扩展性。下面我们将深入解析这四大核心API的功能特性、参数细节和使用场景。
1. create_collection - 集合创建与管理
create_collection是构建向量数据库的起点,负责创建和管理数据集合。每个集合都是一个独立的命名空间,包含特定的配置和嵌入函数。
核心功能特性
def create_collection(
name: str,
configuration: Optional[CreateCollectionConfiguration] = None,
metadata: Optional[CollectionMetadata] = None,
embedding_function: Optional[EmbeddingFunction[Embeddable]] = None,
data_loader: Optional[DataLoader[Loadable]] = None,
get_or_create: bool = False
) -> Collection
参数详解
| 参数名 | 类型 | 必需 | 描述 | 示例 |
|---|---|---|---|---|
| name | str | ✅ | 集合的唯一标识名称 | "my_documents" |
| configuration | dict | ❌ | 集合配置参数 | {"hnsw:space": "cosine"} |
| metadata | dict | ❌ | 集合元数据 | {"description": "Research papers"} |
| embedding_function | EmbeddingFunction | ❌ | 自定义嵌入函数 | OpenAIEmbeddingFunction() |
| data_loader | DataLoader | ❌ | 数据加载器(多模态) | ImageDataLoader() |
| get_or_create | bool | ❌ | 存在时获取,不存在时创建 | True |
配置选项详解
Chroma支持丰富的集合配置选项,主要通过configuration参数进行设置:
# HNSW索引配置示例
configuration = {
"hnsw:space": "cosine", # 距离度量:cosine/l2/ip
"hnsw:construction_ef": 200, # 构建时的ef参数
"hnsw:search_ef": 100, # 搜索时的ef参数
"hnsw:M": 16, # 每个节点的最大连接数
"hnsw:num_threads": 4 # 构建索引的线程数
}
# SPANN配置示例(大规模场景)
configuration = {
"spann:space": "l2",
"spann:num_partitions": 1000,
"spann:num_centroids": 10000,
"spann:search_ef": 50
}
使用示例
import chromadb
from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction
# 基础集合创建
client = chromadb.Client()
collection = client.create_collection("research_papers")
# 带自定义嵌入函数的集合
openai_ef = OpenAIEmbeddingFunction(api_key="your-api-key")
collection = client.create_collection(
name="ai_papers",
embedding_function=openai_ef,
metadata={"category": "artificial_intelligence"}
)
# 使用get_or_create模式
collection = client.get_or_create_collection(
name="existing_collection",
configuration={"hnsw:space": "ip"}
)
2. add - 数据插入与更新
add方法负责向集合中添加嵌入向量及其关联数据,支持批量操作和多种数据类型。
核心功能特性
def add(
ids: OneOrMany[ID],
embeddings: Optional[Union[OneOrMany[Embedding], OneOrMany[PyEmbedding]]] = None,
metadatas: Optional[OneOrMany[Metadata]] = None,
documents: Optional[OneOrMany[Document]] = None,
images: Optional[OneOrMany[Image]] = None,
uris: Optional[OneOrMany[URI]] = None
) -> None
参数结构详解
数据类型支持
Chroma的add方法支持多种数据类型输入:
| 数据类型 | 输入格式 | 处理方式 | 使用场景 |
|---|---|---|---|
| 文本文档 | str / List[str] | 自动嵌入或使用预计算向量 | 文档检索、问答系统 |
| 预计算向量 | List[float] / np.array | 直接存储 | 自定义嵌入流水线 |
| 图像数据 | np.array / PIL.Image | 多模态嵌入处理 | 图像检索、跨模态搜索 |
| 元数据 | Dict / List[Dict] | 存储并支持过滤 | 数据分类、属性过滤 |
| URI引用 | str / List[str] | 配合data_loader使用 | 大规模媒体文件 |
批量操作最佳实践
# 批量添加文档(自动嵌入)
documents = [
"Chroma is an AI-native open-source embedding database.",
"It provides a simple API to store and query embeddings.",
"The core API consists of only 4 functions."
]
collection.add(
ids=["doc1", "doc2", "doc3"],
documents=documents,
metadatas=[
{"source": "github", "lang": "en"},
{"source": "docs", "lang": "en"},
{"source": "tutorial", "lang": "en"}
]
)
# 批量添加预计算向量
import numpy as np
embeddings = np.random.rand(100, 384) # 100个384维向量
collection.add(
ids=[f"vec_{i}" for i in range(100)],
embeddings=embeddings,
metadatas=[{"batch": "1"} for _ in range(100)]
)
# 多模态数据添加
collection.add(
ids=["image1", "image2"],
images=[image_array1, image_array2],
documents=["描述文本1", "描述文本2"],
metadatas=[{"type": "photo"}, {"type": "illustration"}]
)
错误处理与验证
add方法包含严格的输入验证:
try:
# 长度不匹配会抛出ValueError
collection.add(
ids=["id1", "id2"],
documents=["only one document"] # 错误:长度不匹配
)
except ValueError as e:
print(f"输入验证错误: {e}")
# 重复ID处理
try:
collection.add(ids=["duplicate_id"], documents=["doc1"])
collection.add(ids=["duplicate_id"], documents=["doc2"]) # 错误:重复ID
except ValueError as e:
print(f"重复ID错误: {e}")
3. query - 智能检索与相似度搜索
query方法是Chroma的核心检索功能,支持多种查询方式和丰富的过滤选项。
核心功能特性
def query(
query_embeddings: Optional[Union[OneOrMany[Embedding], OneOrMany[PyEmbedding]]] = None,
query_texts: Optional[OneOrMany[Document]] = None,
query_images: Optional[OneOrMany[Image]] = None,
query_uris: Optional[OneOrMany[URI]] = None,
ids: Optional[OneOrMany[ID]] = None,
n_results: int = 10,
where: Optional[Where] = None,
where_document: Optional[WhereDocument] = None,
include: Include = ["metadatas", "documents", "distances"]
) -> QueryResult
查询模式对比
过滤条件详解
Chroma提供强大的过滤能力,支持复杂的查询条件:
元数据过滤 (where参数)
# 基础比较操作
where = {"category": "science"} # 等于
where = {"rating": {"$gte": 4}} # 大于等于
where = {"price": {"$lt": 100}} # 小于
where = {"tags": {"$ne": "old"}} # 不等于
# 逻辑运算符
where = {
"$and": [
{"category": "technology"},
{"year": {"$gte": 2020}}
]
}
where = {
"$or": [
{"category": "science"},
{"category": "technology"}
]
}
where = {
"$not": {"status": "archived"}
}
# 数组操作
where = {"tags": {"$contains": "ai"}} # 包含元素
where = {"authors": {"$in": ["John", "Jane"]}} # 在数组中
文档内容过滤 (where_document参数)
# 文本内容搜索
where_document = {"$contains": "artificial intelligence"}
where_document = {"$not_contains": "deprecated"}
where_document = {"$starts_with": "Chapter"}
where_document = {"$ends_with": "conclusion"}
# 正则表达式匹配
where_document = {"$regex": "^[A-Z].*"} # 以大写字母开头
# 组合条件
where_document = {
"$and": [
{"$contains": "machine learning"},
{"$not_contains": "outdated"}
]
}
高级查询示例
# 多模态查询:文本搜图像
results = collection.query(
query_texts=["a beautiful sunset"],
n_results=5,
where={"type": "image", "category": "nature"},
include=["metadatas", "distances", "uris"]
)
# 混合查询:向量+过滤
reference_embedding = np.random.rand(384) # 参考向量
results = collection.query(
query_embeddings=[reference_embedding],
n_results=10,
where={
"$and": [
{"language": "english"},
{"word_count": {"$gte": 500}},
{"published": {"$gte": "2023-01-01"}}
]
},
where_document={"$contains": "artificial intelligence"},
include=["documents", "metadatas", "distances", "embeddings"]
)
# 分页查询
page_size = 20
for page in range(5):
results = collection.query(
query_texts=["quantum computing"],
n_results=page_size,
offset=page * page_size,
include=["documents", "metadatas"]
)
# 处理当前页结果
结果处理与优化
# 结果结构解析
results = collection.query(
query_texts=["query example"],
n_results=3,
include=["metadatas", "documents", "distances", "embeddings"]
)
print("查询结果结构:")
print(f"IDs: {results['ids']}") # 二维列表: [[id1, id2, id3]]
print(f"Documents: {results['documents']}") # 二维列表: [[doc1, doc2, doc3]]
print(f"Metadatas: {results['metadatas']}") # 二维列表: [[meta1, meta2, meta3]]
print(f"Distances: {results['distances']}") # 二维列表: [[dist1, dist2, dist3]]
print(f"Embeddings: {results['embeddings']}") # 二维列表: [[emb1, emb2, emb3]]
# 性能优化建议
# 1. 合理设置n_results,避免返回过多数据
# 2. 使用where过滤减少搜索空间
# 3. 只include需要的字段
# 4. 对高频查询考虑索引优化
4. get - 精确检索与数据管理
get方法提供精确的数据检索功能,支持按ID、条件过滤和分页查询。
核心功能特性
def get(
ids: Optional[OneOrMany[ID]] = None,
where: Optional[Where] = None,
limit: Optional[int] = None,
offset: Optional[int] = None,
where_document: Optional[WhereDocument] = None,
include: Include = ["metadatas", "documents"]
) -> GetResult
与query方法的区别
| 特性 | get方法 | query方法 |
|---|---|---|
| 搜索方式 | 精确匹配 | 相似度搜索 |
| 使用场景 | 数据检索 | 语义搜索 |
| 性能特点 | O(1) 或 O(n) | O(log n) 近似搜索 |
| 结果排序 | 插入顺序 | 相似度排序 |
| 主要参数 | ids, where | query_embeddings, query_texts |
使用模式详解
# 1. 按ID精确检索
results = collection.get(
ids=["doc1", "doc3", "doc5"],
include=["metadatas", "documents", "embeddings"]
)
# 2. 条件过滤检索
results = collection.get(
where={
"category": "research",
"year": {"$gte": 2022}
},
limit=100, # 最多返回100条
offset=0, # 从第0条开始
include=["metadatas", "documents"]
)
# 3. 文档内容过滤
results = collection.get(
where_document={"$contains": "experimental results"},
limit=50,
include=["metadatas", "documents"]
)
# 4. 组合条件查询
results = collection.get(
where={
"$and": [
{"status": "published"},
{"rating": {"$gte": 4.0}},
{"tags": {"$contains": "ai"}}
]
},
where_document={"$contains": "deep learning"},
limit=20,
offset=10,
include=["metadatas", "documents", "embeddings"]
)
# 5. 全量数据导出(分页处理)
all_data = []
page_size = 1000
offset = 0
while True:
results = collection.get(
limit=page_size,
offset=offset,
include=["metadatas", "documents", "embeddings"]
)
if not results["ids"]:
break
all_data.append(results)
offset += page_size
高级使用技巧
# 元数据字段存在性检查
results = collection.get(
where={"description": {"$exists": True}}, # 只返回有description字段的文档
include=["metadatas", "documents"]
)
# 空值处理
results = collection.get(
where={"author": {"$eq": None}}, # 作者字段为空的文档
include=["metadatas", "documents"]
)
# 数组长度过滤
results = collection.get(
where={"tags": {"$size": 5}}, # 恰好有5个标签的文档
include=["metadatas", "documents"]
)
# 正则表达式匹配(元数据字段)
results = collection.get(
where={"email": {"$regex": "@company\\.com$"}}, # 公司邮箱
include=["metadatas", "documents"]
)
# 分页性能优化
def efficient_pagination(collection, batch_size=500):
"""高效分页实现,避免offset过大性能问题"""
all_ids = []
last_id = None
while True:
# 使用ID范围查询替代offset
where = {}
if last_id:
where = {"chroma_id": {"$gt": last_id}}
results = collection.get(
where=where,
limit=batch_size,
include=["ids"] # 只获取ID
)
if not results["ids"]:
break
batch_ids = results["ids"][0]
all_ids.extend(batch_ids)
last_id = batch_ids[-1]
return all_ids
结果处理与转换
# 结果转换为DataFrame
import pandas as pd
results = collection.get(
where={"category": "research"},
include=["metadatas", "documents"]
)
# 转换为结构化DataFrame
df_data = []
for i, doc_id in enumerate(results["ids"][0]):
row = {
"id": doc_id,
"document": results["documents"][0][i],
**results["metadatas"][0][i] # 展开元数据字段
}
df_data.append(row)
df = pd.DataFrame(df_data)
print(df.head())
# 结果统计分析
print(f"总文档数: {len(results['ids'][0])}")
print(f"包含的字段: {list(results.keys())}")
# 元数据字段分布分析
if results["metadatas"]:
metadata_fields = set()
for meta in results["metadatas"][0]:
metadata_fields.update(meta.keys())
print(f"元数据字段: {metadata_fields}")
通过这四大核心API函数的详细解析,我们可以看到Chroma在设计上的简洁性和强大功能。每个API都经过精心设计,既保证了易用性,又提供了丰富的高级功能满足复杂场景需求。
本地内存模式与持久化存储配置
Chroma作为AI原生的开源嵌入数据库,提供了灵活的存储配置选项,让开发者可以根据不同场景需求选择合适的数据持久化策略。本节将深入探讨Chroma的两种主要存储模式:本地内存模式和持久化存储模式,并提供详细的配置指南和最佳实践。
存储模式概述
Chroma支持两种核心存储模式,每种模式都有其特定的使用场景和优势:
本地内存模式配置
本地内存模式是Chroma的默认配置,适合快速原型开发和测试环境。这种模式下所有数据都存储在内存中,程序退出后数据不会保留。
基本使用方法
import chromadb
# 创建内存客户端 - 最简单的方式
client = chromadb.Client()
# 或者使用明确的EphemeralClient
client = chromadb.EphemeralClient()
# 创建集合并添加数据
collection = client.create_collection("my_documents")
collection.add(
documents=["文档1内容", "文档2内容", "文档3内容"],
metadatas=[{"source": "web"}, {"source": "book"}, {"source": "report"}],
ids=["doc1", "doc2", "doc3"]
)
# 查询数据
results = collection.query(
query_texts=["相关文档查询"],
n_results=2
)
内存模式的特点
| 特性 | 描述 | 适用场景 |
|---|---|---|
| 零配置 | 无需指定存储路径 | 快速开始 |
| 高性能 | 内存访问速度快 | 高频查询 |
| 临时性 | 进程退出数据丢失 | 测试开发 |
| 轻量级 | 无磁盘IO开销 | 演示环境 |
持久化存储配置
持久化存储模式将数据保存到磁盘文件中,确保数据在程序重启后仍然可用,适合生产环境和需要数据持久化的场景。
基本配置方法
import chromadb
from pathlib import Path
# 使用默认路径(当前目录下的chroma文件夹)
client = chromadb.PersistentClient()
# 指定自定义存储路径
client = chromadb.PersistentClient(path="./my_chroma_data")
# 使用Path对象指定路径
data_path = Path("/data/chroma/storage")
client = chromadb.PersistentClient(path=data_path)
# 创建集合并添加数据
collection = client.create_collection("persistent_docs")
collection.add(
documents=["持久化文档1", "持久化文档2"],
metadatas=[{"category": "tech"}, {"category": "science"}],
ids=["persistent1", "persistent2"]
)
高级配置选项
除了基本的路径配置,PersistentClient还支持丰富的设置选项:
from chromadb.config import Settings
# 自定义配置持久化客户端
custom_settings = Settings(
persist_directory="/custom/path/chroma_db",
chroma_api_impl="chromadb.api.rust.RustBindingsAPI",
allow_reset=True # 允许重置数据库
)
client = chromadb.PersistentClient(
path="/custom/path/chroma_db",
settings=custom_settings
)
持久化存储目录结构
当使用持久化模式时,Chroma会创建以下目录结构:
chroma_data/
├── chroma.sqlite3 # 主数据库文件
├── collections/ # 集合数据目录
│ ├── {collection_id_1}/ # 单个集合目录
│ │ ├── hnsw_index.bin # HNSW索引文件
│ │ ├── metadata.pkl # 元数据文件
│ │ └── vectors.bin # 向量数据文件
│ └── {collection_id_2}/
└── logs/ # 操作日志目录
配置参数详解
核心配置参数
下表列出了影响存储模式的关键配置参数:
| 参数名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
is_persistent | bool | False | 是否启用持久化模式 |
persist_directory | str | "./chroma" | 持久化数据存储目录 |
chroma_api_impl | str | "chromadb.api.rust.RustBindingsAPI" | API实现类型 |
存储相关配置示例
from chromadb.config import Settings
# 生产环境推荐配置
production_settings = Settings(
is_persistent=True,
persist_directory="/var/lib/chroma/data",
chroma_memory_limit_bytes=2147483648, # 2GB内存限制
allow_reset=False # 生产环境禁用重置
)
# 开发环境配置
development_settings = Settings(
is_persistent=True,
persist_directory="./dev_chroma_data",
allow_reset=True # 开发环境允许重置
)
# 内存优化配置
memory_optimized_settings = Settings(
is_persistent=True,
persist_directory="./chroma_data",
chroma_segment_cache_policy="lru", # LRU缓存策略
chroma_memory_limit_bytes=1073741824 # 1GB内存限制
)
模式切换与数据迁移
在实际项目中,经常需要在不同存储模式之间切换。以下是常见的场景和处理方法:
从内存模式迁移到持久化模式
import chromadb
# 步骤1: 创建内存客户端并加载数据
memory_client = chromadb.EphemeralClient()
memory_collection = memory_client.create_collection("temp_data")
# ... 添加数据到内存集合
# 步骤2: 创建持久化客户端
persistent_client = chromadb.PersistentClient(path="./production_data")
# 步骤3: 重新创建集合并迁移数据
persistent_collection = persistent_client.create_collection(
name="temp_data",
metadata=memory_collection.metadata
)
# 获取内存中的所有数据
all_data = memory_collection.get(include=["documents", "metadatas", "embeddings"])
# 批量添加到持久化集合
persistent_collection.add(
documents=all_data["documents"],
metadatas=all_data["metadatas"],
ids=all_data["ids"],
embeddings=all_data["embeddings"]
)
数据备份与恢复
import shutil
from pathlib import Path
def backup_chroma_data(source_path: str, backup_path: str) -> None:
"""备份Chroma数据目录"""
if Path(source_path).exists():
shutil.copytree(source_path, backup_path)
print(f"备份完成: {source_path} -> {backup_path}")
else:
print("源目录不存在")
def restore_chroma_data(backup_path: str, restore_path: str) -> None:
"""恢复Chroma数据目录"""
if Path(backup_path).exists():
shutil.copytree(backup_path, restore_path)
print(f"恢复完成: {backup_path} -> {restore_path}")
else:
print("备份目录不存在")
# 使用示例
backup_chroma_data("./chroma_data", "./chroma_backup_2024")
性能优化建议
根据不同的使用场景,以下是一些性能优化建议:
内存模式优化
# 对于大量数据的临时处理,使用批量操作
def batch_add_documents(collection, documents, batch_size=1000):
for i in range(0, len(documents), batch_size):
batch = documents[i:i+batch_size]
collection.add(
documents=batch,
ids=[f"doc_{j}" for j in range(i, i+len(batch))]
)
# 使用适当的索引参数
collection = client.create_collection(
"optimized_collection",
metadata={
"hnsw:space": "cosine",
"hnsw:M": 16,
"hnsw:ef_construction": 200
}
)
持久化模式优化
# 使用SSD存储提升IO性能
ssd_settings = Settings(
is_persistent=True,
persist_directory="/mnt/ssd/chroma_data", # SSD路径
chroma_memory_limit_bytes=4294967296 # 4GB内存缓存
)
# 定期维护和优化
def optimize_persistent_storage(client):
"""执行存储优化操作"""
# 压缩数据库
client.compact()
# 清理临时文件
client.cleanup()
# 监控磁盘使用
import psutil
def check_disk_usage(path="./chroma_data"):
usage = psutil.disk_usage(path)
print(f"磁盘使用情况: {usage.percent}%")
return usage.percent < 90 # 确保有10%以上空闲空间
错误处理与故障恢复
在实际使用中,需要考虑各种异常情况:
import os
from chromadb.errors import ChromaError
def safe_persistent_operation():
try:
# 检查存储目录权限
data_path = "./chroma_data"
if not os.access(data_path, os.W_OK):
os.makedirs(data_path, exist_ok=True)
client = chromadb.PersistentClient(path=data_path)
# 正常操作...
except PermissionError as e:
print(f"权限错误: {e}")
# 尝试修复权限或使用备用路径
except ChromaError as e:
print(f"Chroma错误: {e}")
# 处理特定的Chroma错误
except Exception as e:
print(f"未知错误: {e}")
# 通用错误处理
# 自动恢复机制
def resilient_chroma_operation(max_retries=3):
for attempt in range(max_retries):
try:
client = chromadb.PersistentClient(path="./chroma_data")
# 执行操作
return client
except Exception as e:
print(f"尝试 {attempt + 1} 失败: {e}")
if attempt == max_retries - 1:
# 最后一次尝试失败,回退到内存模式
print("回退到内存模式")
return chromadb.EphemeralClient()
最佳实践总结
根据项目需求和环境特点,以下是一些配置建议:
- 开发测试环境:使用内存模式或本地持久化模式,路径设置为项目目录
- 生产环境:使用持久化模式,配置专用存储目录和适当的内存限制
- 大规模数据:使用持久化模式并结合批量操作优化
- 高可用需求:考虑使用远程服务器模式而非本地持久化
通过合理配置存储模式,可以在性能、持久性和开发便利性之间找到最佳平衡点,为AI应用提供稳定可靠的数据存储基础。
集合创建与文档管理操作
Chroma作为AI原生的开源嵌入数据库,其核心API设计简洁而强大,仅需4个主要函数即可完成向量数据库的核心操作。在集合创建与文档管理方面,Chroma提供了直观且灵活的接口,让开发者能够轻松构建和管理向量化数据存储。
集合创建与管理
集合(Collection)是Chroma中组织文档和向量的基本单位,类似于传统数据库中的表。创建集合时,您可以指定名称、元数据配置以及嵌入函数等参数。
创建新集合
import chromadb
# 初始化客户端(内存模式,适合原型开发)
client = chromadb.Client()
# 创建名为"research-papers"的集合
collection = client.create_collection(
name="research-papers",
metadata={"description": "存储学术研究论文的集合", "category": "academic"}
)
获取或创建集合
为了避免重复创建同名集合,Chroma提供了get_or_create_collection方法:
# 如果集合不存在则创建,存在则直接返回
collection = client.get_or_create_collection(
name="research-papers",
metadata={"version": "1.0", "owner": "research-team"}
)
集合配置选项
创建集合时可以指定丰富的配置参数:
collection = client.create_collection(
name="ai-models",
configuration={
"embedding_function": {
"name": "text-embedding-ada-002",
"dimensions": 1536
},
"index": {
"type": "hnsw",
"space": "cosine",
"ef_construction": 200,
"m": 16
}
}
)
文档添加操作
向集合中添加文档是Chroma的核心功能之一。您可以选择提供预计算的嵌入向量,或者让Chroma自动处理文本嵌入。
基本文档添加
# 添加文档到集合中
collection.add(
documents=[
"机器学习是人工智能的核心领域",
"深度学习通过神经网络模拟人脑学习机制",
"Transformer架构 revolutionized自然语言处理"
],
metadatas=[
{"source": "textbook", "year": 2023},
{"source": "research-paper", "author": "Hinton"},
{"source": "blog", "topic": "NLP"}
],
ids=["doc1", "doc2", "doc3"]
)
带自定义嵌入的添加
如果您已有预计算的嵌入向量,可以直接提供:
import numpy as np
# 预计算的嵌入向量
custom_embeddings = [
[0.1, 0.2, 0.3, 0.4], # doc1的嵌入
[0.5, 0.6, 0.7, 0.8], # doc2的嵌入
[0.9, 1.0, 1.1, 1.2] # doc3的嵌入
]
collection.add(
documents=["文档内容1", "文档内容2", "文档内容3"],
embeddings=custom_embeddings,
ids=["custom1", "custom2", "custom3"]
)
多媒体内容支持
Chroma还支持图像和其他多媒体内容的嵌入:
# 添加图像文档
collection.add(
images=[image_data1, image_data2], # PIL图像或numpy数组
metadatas=[
{"type": "diagram", "category": "architecture"},
{"type": "photo", "location": "lab"}
],
ids=["img1", "img2"]
)
文档查询与检索
添加文档后,您可以基于内容相似性进行查询:
# 查询相似的文档
results = collection.query(
query_texts=["人工智能的最新进展"],
n_results=3,
where={"source": "research-paper"}, # 元数据过滤
include=["metadatas", "documents", "distances"]
)
print("最相关的文档:")
for i, (doc, meta, dist) in enumerate(zip(
results['documents'][0],
results['metadatas'][0],
results['distances'][0]
)):
print(f"{i+1}. {doc} (相似度: {1-dist:.3f})")
print(f" 元数据: {meta}")
文档管理操作
获取文档信息
# 获取特定ID的文档
documents = collection.get(
ids=["doc1", "doc2"],
include=["metadatas", "documents"]
)
# 使用条件过滤获取文档
filtered_docs = collection.get(
where={"year": {"$gte": 2022}}, # 2022年及以后的文档
where_document={"$contains": "神经网络"} # 包含"神经网络"的文档
)
更新文档内容
# 更新文档的元数据
collection.update(
ids=["doc1"],
metadatas=[{"year": 2024, "status": "updated"}]
)
# 更新文档内容和嵌入
collection.update(
ids=["doc2"],
documents=["更新后的文档内容"],
embeddings=[[0.15, 0.25, 0.35, 0.45]]
)
删除文档
# 删除特定ID的文档
collection.delete(ids=["doc3"])
# 基于条件删除文档
collection.delete(
where={"source": "blog"} # 删除所有来源为blog的文档
)
批量操作与性能优化
对于大规模数据,Chroma支持高效的批量操作:
# 批量添加文档
batch_size = 1000
documents_batch = [...] # 1000个文档
embeddings_batch = [...] # 对应的嵌入向量
collection.add(
documents=documents_batch,
embeddings=embeddings_batch,
ids=[f"doc_{i}" for i in range(batch_size)]
)
集合操作流程图
以下是集合创建与文档管理的典型工作流程:
高级配置选项
Chroma提供了丰富的高级配置来优化集合性能:
| 配置项 | 描述 | 推荐值 |
|---|---|---|
index.type | 索引类型 | hnsw(分层可导航小世界) |
index.space | 距离度量空间 | cosine(余弦相似度) |
index.ef_construction | 构建时的搜索范围 | 200-400 |
index.m | 每个节点的连接数 | 16-64 |
embedding_function | 嵌入函数配置 | 根据模型特性设置 |
# 高级集合配置示例
advanced_collection = client.create_collection(
name="high-performance-collection",
configuration={
"embedding_function": {
"name": "all-MiniLM-L6-v2",
"dimensions": 384,
"model": "sentence-transformers/all-MiniLM-L6-v2"
},
"index": {
"type": "hnsw",
"space": "ip", # 内积空间
"ef_construction": 300,
"m": 32,
"ef_search": 100
},
"optimization": {
"batch_size": 500,
"compaction_threshold": 10000
}
}
)
错误处理与验证
在文档管理操作中,适当的错误处理至关重要:
try:
collection.add(
documents=["新文档"],
ids=["existing_id"] # 如果ID已存在会抛出异常
)
except ValueError as e:
print(f"添加文档失败: {e}")
# 处理重复ID的情况
collection.update(
ids=["existing_id"],
documents=["更新后的内容"]
)
# 验证操作结果
doc_count = collection.count()
print(f"集合中总文档数: {doc_count}")
if doc_count == 0:
print("警告: 集合为空,请检查添加操作")
通过上述集合创建与文档管理操作,您可以高效地构建和管理Chroma向量数据库,为AI应用提供强大的语义搜索和相似性检索能力。Chroma的简洁API设计使得即使是对向量数据库不熟悉的开发者也能快速上手,同时提供了足够的高级功能来满足复杂应用场景的需求。
相似性搜索与查询功能实践
Chroma作为AI原生的向量数据库,其核心功能之一就是高效的相似性搜索与查询。在本节中,我们将深入探讨Chroma的查询API、距离计算机制、过滤功能以及实际应用场景。
查询API详解
Chroma的查询功能主要通过collection.query()方法实现,该方法提供了丰富的参数配置:
def query(
self,
query_embeddings: Optional[Union[OneOrMany[Embedding], OneOrMany[PyEmbedding]]] = None,
query_texts: Optional[OneOrMany[Document]] = None,
query_images: Optional[OneOrMany[Image]] = None,
query_uris: Optional[OneOrMany[URI]] = None,
ids: Optional[OneOrMany[ID]] = None,
n_results: int = 10,
where: Optional[Where] = None,
where_document: Optional[WhereDocument] = None,
include: Include = ["metadatas", "documents", "distances"],
) -> QueryResult:
查询参数说明
| 参数名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| query_embeddings | Embedding[] | 直接提供查询向量 | None |
| query_texts | Document[] | 提供查询文本,自动转换为向量 | None |
| query_images | Image[] | 提供查询图像,自动转换为向量 | None |
| query_uris | URI[] | 提供URI,配合数据加载器使用 | None |
| n_results | int | 返回的最相似结果数量 | 10 |
| where | Where | 元数据过滤条件 | None |
| where_document | WhereDocument | 文档内容过滤条件 | None |
| include | Include[] | 返回结果包含的字段 | ["metadatas", "documents", "distances"] |
距离计算机制
Chroma支持多种距离计算函数,用于衡量向量之间的相似性:
距离函数实现
def l2(x: Vector, y: Vector) -> float:
"""欧几里得距离平方"""
return (np.linalg.norm(x - y) ** 2).item()
def cosine(x: Vector, y: Vector) -> float:
"""余弦相似度 (1 - 余弦距离)"""
NORM_EPS = 1e-30
if x.dtype == np.float16 or y.dtype == np.float16:
NORM_EPS = 1e-7
return (1.0 - np.dot(x, y) / ((np.linalg.norm(x) * np.linalg.norm(y)) + NORM_EPS)).item()
def ip(x: Vector, y: Vector) -> float:
"""内积相似度 (1 - 内积)"""
return (1.0 - np.dot(x, y)).item()
过滤功能实践
Chroma提供了强大的过滤功能,支持元数据过滤和文档内容过滤:
元数据过滤 (where)
# 简单等值过滤
results = collection.query(
query_texts=["机器学习"],
where={"category": "technology"},
n_results=5
)
# 数值范围过滤
results = collection.query(
query_texts=["深度学习"],
where={"rating": {"$gte": 4.5}},
n_results=3
)
# 逻辑运算符过滤
results = collection.query(
query_texts=["人工智能"],
where={
"$and": [
{"category": "ai"},
{"published": True},
{"views": {"$gt": 1000}}
]
},
n_results=5
)
文档内容过滤 (where_document)
# 包含特定文本
results = collection.query(
query_texts=["神经网络"],
where_document={"$contains": "深度学习"},
n_results=3
)
# 不包含特定文本
results = collection.query(
query_texts=["机器学习"],
where_document={"$not_contains": "过拟合"},
n_results=5
)
# 逻辑组合过滤
results = collection.query(
query_texts=["自然语言处理"],
where_document={
"$or": [
{"$contains": "Transformer"},
{"$contains": "BERT"}
]
},
n_results=4
)
多模态查询示例
Chroma支持多种数据类型的查询:
# 文本查询
text_results = collection.query(
query_texts=["什么是机器学习"],
n_results=3,
include=["metadatas", "documents", "distances"]
)
# 向量查询(直接提供嵌入向量)
vector_results = collection.query(
query_embeddings=[[0.1, 0.2, 0.3, 0.4]],
n_results=5,
include=["metadatas", "distances"]
)
# 图像查询(需要配置图像嵌入函数)
image_results = collection.query(
query_images=[image_data],
n_results=3,
include=["metadatas", "distances"]
)
查询结果处理
查询返回的结果包含丰富的信息:
{
'ids': [['id1', 'id2', 'id3']],
'distances': [[0.15, 0.23, 0.31]],
'metadatas': [[
{'title': '机器学习基础', 'category': 'ai'},
{'title': '深度学习导论', 'category': 'ai'},
{'title': '神经网络原理', 'category': 'ml'}
]],
'embeddings': None, # 默认不返回
'documents': [[
'机器学习是人工智能的核心技术...',
'深度学习是机器学习的一个分支...',
'神经网络模仿人脑神经元结构...'
]],
'uris': None,
'data': None
}
性能优化技巧
批量查询
# 批量查询提高效率
batch_queries = [
"机器学习",
"深度学习",
"自然语言处理",
"计算机视觉"
]
batch_results = collection.query(
query_texts=batch_queries,
n_results=3,
include=["metadatas", "distances"]
)
结果字段控制
# 只返回必要字段,减少数据传输
minimal_results = collection.query(
query_texts=["查询文本"],
n_results=5,
include=["ids", "distances"] # 只返回ID和距离
)
# 返回完整信息
full_results = collection.query(
query_texts=["查询文本"],
n_results=5,
include=["metadatas", "documents", "distances", "embeddings"]
)
实际应用场景
文档检索系统
def search_documents(query: str, category: str = None, min_rating: float = None):
"""文档检索函数"""
where_clause = {}
if category:
where_clause["category"] = category
if min_rating is not None:
where_clause["rating"] = {"$gte": min_rating}
results = collection.query(
query_texts=[query],
where=where_clause if where_clause else None,
n_results=10,
include=["metadatas", "documents", "distances"]
)
return format_results(results)
def format_results(results):
"""格式化查询结果"""
formatted = []
for i in range(len(results['ids'][0])):
item = {
'id': results['ids'][0][i],
'distance': results['distances'][0][i],
'metadata': results['metadatas'][0][i],
'document': results['documents'][0][i]
}
formatted.append(item)
return formatted
推荐系统
def get_recommendations(user_query: str, user_preferences: dict):
"""基于用户偏好的推荐"""
# 构建个性化过滤条件
where_filters = {
"$and": [
{"category": {"$in": user_preferences.get("preferred_categories", [])}},
{"difficulty": {"$lte": user_preferences.get("max_difficulty", 5)}}
]
}
results = collection.query(
query_texts=[user_query],
where=where_filters,
n_results=user_preferences.get("num_recommendations", 5),
include=["metadatas", "documents", "distances"]
)
return results
高级查询模式
混合查询策略
def hybrid_search(query_text: str, filter_criteria: dict, boost_recent: bool = False):
"""混合搜索:结合语义搜索和过滤"""
base_query = {
"query_texts": [query_text],
"n_results": 20, # 获取更多结果进行后续处理
"include": ["metadatas", "distances"]
}
# 添加过滤条件
if filter_criteria:
base_query["where"] = filter_criteria
# 执行查询
initial_results = collection.query(**base_query)
# 后续处理(如时间加权等)
if boost_recent:
final_results = apply_recency_boost(initial_results)
else:
final_results = initial_results
return final_results[:10] # 返回最终Top-10
通过上述实践,我们可以看到Chroma提供了强大而灵活的相似性搜索功能,支持多种查询模式、过滤条件和结果处理方式,能够满足各种复杂的应用场景需求。
总结
Chroma通过四大核心API函数提供了简洁而强大的向量数据库功能。create_collection用于集合创建与管理,add负责数据插入与更新,query实现智能检索与相似度搜索,get提供精确检索与数据管理。文章详细探讨了本地内存模式和持久化存储的配置方法,集合创建与文档管理的操作实践,以及相似性搜索的多模态查询功能和过滤机制。Chroma的设计既保证了易用性,又提供了丰富的高级功能,能够满足从快速原型开发到生产环境的各类应用场景需求,为AI应用提供稳定可靠的数据存储和检索基础。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



