共计 2695 个字符,预计需要花费 7 分钟才能阅读完成。
在 AI 应用开发中,非结构化数据(如文本、图像、音频)的处理一直是个棘手问题。传统 SQL 数据库虽然成熟稳定,但面对向量化后的高维数据查询时,就像用螺丝刀开红酒——工具根本不匹配。而专为 AI 设计的向量数据库如 Chroma,通过近似最近邻 (ANN) 算法,能在毫秒级完成海量向量的相似度搜索,这正是构建推荐系统、语义搜索等场景的刚需。

本文将带您用 SpringBoot+SpringAI 快速打通 Chroma 向量数据库,全程采用容器化部署和现代 Java 技术栈。所有代码示例均基于 Java 17 和 Spring Boot 3.x,包含 Lombok 简化代码和配置项的环境变量注入说明。
环境准备与项目初始化
- 启动 Chroma 服务(Docker 版)
推荐使用官方镜像的持久化模式,数据会保存在 chroma_data 目录:
docker run -d -p 8000:8000 \
-v ./chroma_data:/chroma/chroma \
ghcr.io/chroma-core/chroma:latest
- SpringBoot 项目基础依赖
在 pom.xml 中添加关键依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-chroma-store-spring-boot-starter</artifactId>
<version>0.8.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
核心配置与数据操作
步骤一:配置向量客户端
@Configuration
@RequiredArgsConstructor
public class ChromaConfig {@Value("${chroma.host:localhost}")
private String host;
@Bean
public ChromaApi chromaApi() {return new ChromaApi(host, 8000);
}
@Bean
public VectorStore chromaStore(ChromaApi api, EmbeddingClient embeddingClient) {return new ChromaVectorStore(api, embeddingClient);
}
}
步骤二:实现 CRUD Repository
采用 Spring Data 风格封装常用操作:
public interface DocumentRepository {String addDocument(Document doc);
List<Document> searchSimilar(
String queryText,
int topK,
Map<String, String> filters);
@Data
@Builder
class Document {
private String id;
private String content;
private Map<String, String> metadata;
}
}
步骤三:REST 接口示例
带分页的相似度搜索接口实现:
@RestController
@RequiredArgsConstructor
public class SearchController {
private final DocumentRepository repo;
@PostMapping("/search")
public Page<Document> search(
@RequestBody SearchRequest request,
@PageableDefault Pageable pageable) {
List<Document> results = repo.searchSimilar(request.query(),
pageable.getPageSize(),
request.filters());
return new PageImpl<>(results, pageable, results.size());
}
@Data
public static class SearchRequest {
private String query;
private Map<String, String> filters;
}
}
性能优化实战
批量写入吞吐量测试
使用 @Benchmark 测试不同批次大小的写入速度:
| 批次大小 | 吞吐量(vectors/s) |
|---|---|
| 10 | 1,200 |
| 100 | 8,500 |
| 1000 | 32,000 |
建议实际业务中采用 200-500 的批次大小
索引类型对比
通过 create_collection 时指定索引类型:
Map<String, Object> params = Map.of(
"hnsw:space", "cosine",
"hnsw:M", 16
);
collection = client.createCollection(name, params);
不同配置的查询延迟对比:
| 参数组合 | 平均延迟(ms) |
|---|---|
| M=8, ef=100 | 12.3 |
| M=16, ef=200 | 18.7 |
| M=32, ef=500 | 34.2 |
生产环境要点
- 向量维度校验
在写入前必须检查维度是否匹配:
void validateDimensions(float[] vector) {if (vector.length != 1536) { // 假设使用 text-embedding-3-large
throw new IllegalArgumentException("维度不匹配");
}
}
- 连接池配置
在 application.yml 中调整 HTTP 客户端:
spring:
ai:
chroma:
client:
max-connections: 50
connection-timeout: 5s
- 持久化策略
Chroma 支持两种模式:
– 内存模式:重启数据丢失
– 磁盘模式(需挂载 volume)
延伸思考
当您完成基础集成后,可以进一步探索:
-
混合查询方案:结合 PostgreSQL 的 pgvector 扩展,先通过 SQL 过滤再向量搜索
-
分布式集群 :使用 Chroma 的横向扩展方案,通过
chroma/core/worker.py启动多个 worker -
冷热分离:对高频访问的集合使用内存模式,历史数据存入磁盘
完整的示例项目已发布在 GitHub,包含 Docker Compose 文件和性能测试脚本。在实际项目中,建议结合 Prometheus 监控内存和查询延迟指标,根据业务特点持续调优。
