版本:v1.0 | 适用人群:Java AI 开发小白/企业级 RAG 开发工程师 | 前置环境:JDK17+、Docker、Maven/Gradle
一、文档说明
本文档是面向小白的向量数据库从入门到企业级落地完整笔记,覆盖小白开发所需的全部内容,无需额外查阅资料,可直接用于项目开发,核心涵盖:
-
向量数据库核心概念(含 Milvus 三种向量类型详解,小白可直接理解)
-
Milvus/Redis Stack 一键部署(复制命令即可运行,附详细步骤)
-
三大 Java AI 框架完整可运行代码(LangChain4j、Spring AI、Spring AI Alibaba,与你提供的代码完全匹配)
-
企业级最佳实践、小白避坑指南、常见问题排查速查表
-
小白上手完整步骤(从部署到代码运行,一步到位)
二、向量数据库核心基础(小白必懂)
2.1 为什么需要向量数据库?
在 RAG(检索增强生成)开发中,核心流程是:
非结构化数据(文本/图片/音频) → 向量化(Embedding 模型编码) → 向量数据库存储 → 语义相似性检索
大白话:向量数据库就是专门存储「语义身份证」的数据库,能在百万/亿级数据中,毫秒级找到和查询内容语义最相似的结果,比传统数据库的"逐字比对"快得多。
2.2 Milvus 三大向量类型(重点!开发必选对)
Milvus 是生产级向量数据库,支持 3 种核心向量字段类型,开发时必须根据场景选择,选错会导致检索失败或性能极差,小白重点记下表:
| 向量类型 | 全称 | 核心说明(小白版) | 适用场景 | 简单示例 |
|---|---|---|---|---|
| FLOAT_VECTOR | 密集浮点向量 | 每个维度都有浮点数(比如0.123、-0.456),无空值,语义信息最完整,日常开发90%场景首选 | 文本语义检索、通用向量存储、RAG 知识库(最常用) | [0.123, -0.456, 0.789, 0.234, ...](512/768/1024维) |
| SPARSE_FLOAT_VECTOR | 稀疏浮点向量 | 大部分维度值为 0,仅少数维度有有效值,体积小、检索快,适合关键词匹配 | 全文关键词检索、BM25 算法场景、大文本分词检索 | [0, 0, 0.512, 0, 0, 0.876, 0, ...] |
| BINARY_VECTOR | 二进制向量 | 仅存储 0 和 1 两个值,体积极小、检索速度极快,适合简单特征匹配 | 图片指纹、人脸特征、哈希值检索、海量二进制特征匹配 | [1, 0, 1, 0, 1, 1, 0, ...] |
2.3 核心术语(小白版,不用记复杂定义)
| 术语 | 大白话解释 |
|---|---|
| Collection(集合) | 相当于 MySQL 的「表」,是 Milvus 存储数据的最小逻辑单元,里面存向量和标量数据 |
| 标量字段(Metadata) | 相当于 MySQL 的「普通列」,存储结构化信息(id、标题、创建时间、分类等),用于检索时过滤(比如只查"2024年的文档") |
| 向量字段 | 专门存储上述 3 种向量的字段,是相似检索的核心,必须和 Embedding 模型输出维度一致 |
| 相似性度量 | 衡量两个向量相似度的算法,决定了"怎么判断两个向量像不像" |
| nprobe | Milvus 检索核心调优参数,值越大召回率越高(找的越全)、检索越慢;值越小召回率越低、检索越快,小白测试用50即可 |
2.4 常用相似性度量(小白直接抄,不用理解原理)
| 度量算法 | 取值范围 | 相似度判断 | 推荐使用场景 |
|---|---|---|---|
| 余弦相似度(COSINE) | [-1, 1] | 值越大越相似 | 文本语义检索(FLOAT_VECTOR 首选,小白最常用) |
| 内积(IP) | [-1, 1] | 值越大越相似 | 归一化后的向量检索(小白暂时用不到) |
| 欧氏距离(L2) | [0, +∞) | 值越小越相似 | 通用向量、图片特征检索 |
| 汉明距离(HAMMING) | [0, 向量维度] | 值越小越相似 | 二进制向量(BINARY_VECTOR),比如图片指纹 |
| BM25 | [0, +∞) | 值越大越相似 | 稀疏向量全文检索(SPARSE_FLOAT_VECTOR) |
小白提示:日常开发只记「余弦相似度」(文本)和「汉明距离」(二进制)即可,其他场景很少用到。
三、Milvus 生产级向量数据库部署
3.1 核心组件说明(小白不用深入,知道作用即可)
Milvus 生产环境由 3 个核心组件组成,docker-compose 一键部署会自动拉起,不用手动配置:
-
Milvus Standalone:核心服务,处理向量存储、检索请求,默认端口
19530(重点记这个端口) -
etcd:元数据存储,管理 Collection 结构、集群状态(相当于"系统管理员")
-
MinIO:对象存储,持久化向量数据,防止容器删除后数据丢失(相当于"硬盘")
3.2 Docker Compose 一键部署(小白复制即用)
步骤:
-
新建一个空文件夹(比如命名为
milvus-docker),用于存放部署文件和数据 -
在该文件夹中新建
docker-compose.yml文件,复制以下内容(不用修改任何配置) -
打开终端,进入该文件夹,执行启动命令即可
yaml
version: '3.5'
services:
# 元数据存储:etcd(系统管理员,管理集群状态)
etcd:
container_name: milvus-etcd
image: quay.io/coreos/etcd:v3.5.5
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
- ETCD_SNAPSHOT_COUNT=50000
volumes:
- ./milvus/etcd:/etcd # 数据持久化,本地目录:容器目录
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 30s
timeout: 20s
retries: 3
# 对象存储:MinIO(硬盘,持久化向量数据)
minio:
container_name: milvus-minio
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin # 默认用户名
MINIO_SECRET_KEY: minioadmin # 默认密码
volumes:
- ./milvus/minio:/minio_data # 数据持久化
command: minio server /minio_data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
ports:
- "9000:9000"
- "9001:9001"
# Milvus 核心服务(处理向量存储和检索)
standalone:
container_name: milvus-standalone
image: milvusdb/milvus:v2.3.1 # 稳定版本,小白不建议升级
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: etcd:2379 # 连接etcd
MINIO_ADDRESS: minio:9000 # 连接MinIO
volumes:
- ./milvus/milvus:/var/lib/milvus # 数据持久化
ports:
- "19530:19530" # 核心端口,必须开放
- "9091:9091" # 监控端口,可选
depends_on: # 依赖etcd和minio,先启动这两个服务
- "etcd"
- "minio"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 30s
timeout: 20s
retries: 3
# 容器互通网络(不用修改)
networks:
default:
name: milvus
启动命令(复制到终端执行):
bash
# 后台启动所有服务(不会占用终端)
docker-compose up -d
# 查看服务状态,确保3个容器都是 Up 状态(关键!)
docker-compose ps
小白注意:如果执行命令后,有容器不是 Up 状态,执行 docker-compose logs 容器名 查看报错,大概率是端口被占用,关闭占用端口的程序即可。
3.3 可视化工具 Attu(小白必用,不用写代码)
Attu 是 Milvus 官方可视化工具,小白可以用它手动管理 Collection、查看数据、测试检索,不用写一行代码,步骤如下:
-
下载地址:https://zilliz.com/attu(选择对应系统版本,比如Windows、Mac)
-
安装后打开,输入连接地址
127.0.0.1:19530,点击"连接"即可(无需用户名密码) -
核心功能(小白常用):
-
创建/删除 Collection(可选择向量类型,比如 FLOAT_VECTOR)
-
手动插入数据(测试用,不用写代码)
-
执行向量检索(验证检索功能是否正常)
-
查看集群状态(内存、CPU使用情况)
-
四、Redis Stack 轻量级向量数据库
4.1 适用场景(小白明确选型)
Redis Stack 是 Redis 的增强版,集成了向量搜索功能,适合以下场景,不适合生产级海量数据:
-
小数据量(万级向量以内)
-
快速原型验证、Demo 开发(不想部署复杂的 Milvus)
-
已有 Redis 技术栈,不想额外部署其他数据库
4.2 Docker 一键部署(小白复制即用)
bash
# 拉取 Redis Stack 镜像(首次执行,会自动下载)
docker pull redis/redis-stack
# 启动容器(端口映射+数据持久化)
docker run -d \
--name my-redis-stack \
-p 8001:8001 \ # RedisInsight 可视化端口
-p 6379:6379 \ # Redis 默认端口(向量存储核心端口)
-v ./redisstack/data:/data \ # 数据持久化,防止容器删除丢失数据
redis/redis-stack
4.3 可视化工具(RedisInsight)
Redis Stack 自带可视化工具,无需额外下载:
-
访问地址:
http://127.0.0.1:8001(浏览器打开即可) -
核心功能:查看向量索引、手动插入向量、测试检索、管理 Redis 数据
五、三大 Java AI 框架完整实战代码(小白可直接复制运行)
5.1 前置说明(小白必看)
所有示例均使用 BgeSmallZhV15 中文轻量 Embedding 模型,输出 512 维 FLOAT_VECTOR 密集向量,和你提供的代码完全匹配,无需修改维度,直接复制到 IDEA 即可运行。
前置条件:已部署 Milvus/Redis Stack,且服务正常运行(用 Attu/RedisInsight 确认连接正常)。
5.2 LangChain4j 集成 Milvus(最稳定、生态最全,小白首选)
5.2.1 Maven 依赖(复制到 pom.xml 中)
xml
<!-- LangChain4j Milvus 集成(核心依赖) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-milvus</artifactId>
<version>1.0.0-beta2</version>
</dependency>
<!-- 中文 Embedding 模型(BgeSmallZhV15,生成512维FLOAT_VECTOR) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embedding-bge-small-zh-v15</artifactId>
<version>1.0.0-beta2</version>
</dependency>
5.2.2 完整可运行代码(全注释,小白能看懂每一步)
java
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.bgesmallzhv15.BgeSmallZhV15EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.milvus.MilvusEmbeddingStore;
import java.util.List;
/**
* LangChain4j + Milvus 完整示例
* 对应你提供的代码逻辑:向量存储、数据插入、相似检索
* 小白直接复制到 IDEA,运行 main 方法即可
*/
public class LangChain4jMilvusDemo {
public static void main(String[] args) {
// ====================== 1. 初始化 Milvus 向量存储 ======================
// 配置和你提供的代码一致,仅添加注释,小白可直接用
EmbeddingStore<TextSegment> embeddingStore = MilvusEmbeddingStore.builder()
.uri("http://127.0.0.1:19530") // Milvus 连接地址(固定,和Attu一致)
.collectionName("my_collection") // 集合名称(自定义,Attu中可查看)
.dimension(512) // 向量维度,必须和模型输出一致(BgeSmallZhV15是512维)
.vectorFieldName("vector") // 向量字段名(自定义,和Attu中schema一致)
.nprobe(50) // 检索调优参数,小白固定用50即可
.build();
// ====================== 2. 初始化 Embedding 模型 ======================
// 对应你提供的 BgeSmallZhV15EmbeddingModel,生成512维FLOAT_VECTOR
EmbeddingModel embeddingModel = new BgeSmallZhV15EmbeddingModel();
// ====================== 3. 数据向量化 + 存入 Milvus ======================
// 对应你提供的核心逻辑:TextSegment(文本片段)→ 向量化 → add 存入Milvus
// 示例1:体育类文本(用于测试检索)
TextSegment segment1 = TextSegment.from("我喜欢踢足球,每周都会和朋友去球场踢球。");
Embedding embedding1 = embeddingModel.embed(segment1).content(); // 文本转向量(FLOAT_VECTOR)
embeddingStore.add(embedding1, segment1); // 向量+原文存入Milvus
// 示例2:天气类文本(用于对比检索结果)
TextSegment segment2 = TextSegment.from("今天天气真好,阳光明媚,温度25度,适合出门散步。");
Embedding embedding2 = embeddingModel.embed(segment2).content();
embeddingStore.add(embedding2, segment2);
// 示例3:技术类文本(补充示例,小白可修改成自己的文本)
TextSegment segment3 = TextSegment.from("在 RAG 应用中,temperature 参数控制大模型输出的随机性。");
Embedding embedding3 = embeddingModel.embed(segment3).content();
embeddingStore.add(embedding3, segment3);
System.out.println("数据插入 Milvus 成功!");
// ====================== 4. 向量相似性检索(核心功能) ======================
// 对应你提供的检索逻辑,模拟用户提问,找到相似文本
String queryText = "你平时喜欢什么运动?"; // 检索问句(小白可修改)
Embedding queryEmbedding = embeddingModel.embed(queryText).content(); // 问句转向量
// 构建检索请求,设置返回结果数量
EmbeddingSearchRequest searchRequest = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding) // 检索向量(问句的向量)
.maxResults(10) // 最多返回10条相似结果
.build();
// 执行检索,获取匹配结果
List<EmbeddingMatch<TextSegment>> matches = embeddingStore.search(searchRequest).matches();
// ====================== 5. 输出检索结果(小白重点看) ======================
System.out.println("\n===== 检索结果(问句:" + queryText + ") =====");
for (int i = 0; i < matches.size(); i++) {
EmbeddingMatch<TextSegment> match = matches.get(i);
// 相似度得分(余弦相似度,越接近1越相似)
System.out.println("【Top" + (i+1) + "】相似度得分:" + match.score());
// 匹配到的原文(小白可验证是否符合预期)
System.out.println("匹配文本:" + match.embedded().text());
System.out.println("----------------------------------------");
}
}
}
5.2.3 LangChain4j 集成 Redis Stack 代码(轻量场景用)
依赖(复制到 pom.xml):
xml
<!-- LangChain4j Redis 集成 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-community-redis</artifactId>
<version>1.0.0-beta2</version>
<exclusions>
<!-- 排除旧版jedis,避免版本冲突(小白不用管) -->
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Redis 客户端(新版,避免冲突) -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>5.2.0</version>
</dependency>
<!-- 中文 Embedding 模型(和上面一致) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embedding-bge-small-zh-v15</artifactId>
<version>1.0.0-beta2</version>
</dependency>
完整代码(可直接运行):
java
import dev.langchain4j.community.store.embedding.redis.RedisEmbeddingStore;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.onnx.bgesmallzhv15.BgeSmallZhV15EmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingMatch;
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
import dev.langchain4j.store.embedding.EmbeddingStore;
import java.util.List;
/**
* LangChain4j + Redis Stack 示例(轻量场景)
* 小白直接复制运行,前提是 Redis Stack 已部署
*/
public class LangChain4jRedisDemo {
public static void main(String[] args) {
// 1. 初始化 Redis 向量存储(和你提供的代码一致,添加注释)
EmbeddingStore<TextSegment> embeddingStore = RedisEmbeddingStore.builder()
.host("127.0.0.1") // Redis 地址(本地部署,固定)
.port(6379) // Redis 默认端口(固定)
.indexName("rag_demo") // 向量索引名(自定义)
.dimension(512) // 向量维度,和模型一致
.build();
// 2. 初始化 Embedding 模型(和上面 Milvus 示例一致)
EmbeddingModel embeddingModel = new BgeSmallZhV15EmbeddingModel();
// 3. 插入数据(和 Milvus 示例逻辑一致)
TextSegment segment1 = TextSegment.from("我喜欢踢足球。");
Embedding embedding1 = embeddingModel.embed(segment1).content();
embeddingStore.add(embedding1, segment1);
TextSegment segment2 = TextSegment.from("今天天气很好。");
Embedding embedding2 = embeddingModel.embed(segment2).content();
embeddingStore.add(embedding2, segment2);
// 4. 检索(和 Milvus 示例逻辑一致)
Embedding queryEmbedding = embeddingModel.embed("你喜欢什么运动?").content();
EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(10)
.build();
List<EmbeddingMatch<TextSegment>> matches = embeddingStore.search(request).matches();
// 5. 输出结果
System.out.println("===== Redis 检索结果 =====");
matches.forEach(match -> {
System.out.println("相似度:" + match.score());
System.out.println("文本:" + match.embedded().text());
System.out.println("---------------------");
});
}
}
5.3 Spring AI 集成 Milvus(Spring 生态首选,企业级常用)
5.3.1 Maven 依赖(Spring Boot 项目,复制到 pom.xml)
xml
<!-- Spring Boot 父依赖(必须,小白不要修改版本) -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring AI 核心依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Spring AI Milvus 集成(自动装配,不用手动创建对象) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-milvus-store-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
<!-- 本地 Embedding 模型(BgeSmallZhV15) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-transformers-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Spring Web(用于开发接口,小白可测试) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
5.3.2 配置文件 application.yml(新建,复制即用)
yaml
spring:
ai:
# Milvus 配置(和部署的 Milvus 一致)
vectorstore:
milvus:
client:
uri: http://127.0.0.1:19530
collection-name: spring_ai_collection # 集合名,自定义
dimension: 512 # 向量维度,和模型一致
vector-field-name: vector # 向量字段名,自定义
# Embedding 模型配置(不用修改)
embedding:
transformers:
model-name: BAAI/bge-small-zh-v1.5
cache:
enabled: true
5.3.3 业务服务类(Service,小白可直接复制)
java
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* Spring AI Milvus 业务服务
* 对应你提供的核心逻辑:注入存储对象、add插入、search检索
* 小白可直接调用该类的方法,不用手动处理向量转换
*/
@Service
public class MilvusService {
// 注入向量存储对象(Spring 自动装配,不用手动new)
private final VectorStore vectorStore;
// 构造器注入(Spring 自动完成,小白不用修改)
public MilvusService(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
/**
* 插入文档到 Milvus(小白调用示例:addDocument("足球", "我喜欢踢足球"))
* @param title 文档标题(元数据,标量字段)
* @param content 文档内容(自动向量化,无需手动处理)
*/
public void addDocument(String title, String content) {
// 创建文档对象,添加元数据(标量字段,用于后续筛选)
Document document = new Document(
content,
Map.of("title", title, "type", "knowledge") // 自定义元数据
);
// 插入 Milvus(自动完成向量化,无需手动调用Embedding模型)
vectorStore.add(List.of(document));
}
/**
* 相似性检索(小白调用示例:searchSimilar("你喜欢什么运动?", 5))
* @param query 检索问句
* @param topK 返回结果数量
* @return 相似文档列表(包含相似度得分和原文)
*/
public List<Document> searchSimilar(String query, int topK) {
// 构建检索请求,可添加筛选条件
SearchRequest request = SearchRequest.builder()
.query(query) // 检索问句
.topK(topK) // 返回前K个结果
// 可选:标量字段过滤,比如只查 type=knowledge 的文档(小白可注释)
// .filterExpression("type == 'knowledge'")
.build();
// 执行检索,返回相似文档
return vectorStore.similaritySearch(request);
}
}
5.3.4 测试接口(Controller,小白可直接访问测试)
java
import org.springframework.ai.document.Document;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/milvus") // 接口前缀,固定
public class MilvusController {
private final MilvusService milvusService;
// 构造器注入服务(Spring 自动完成)
public MilvusController(MilvusService milvusService) {
this.milvusService = milvusService;
}
/**
* 插入文档接口(小白可通过浏览器访问测试)
* 访问示例:GET http://localhost:8080/milvus/add?title=足球&content=我喜欢踢足球
*/
@GetMapping("/add")
public String addDocument(@RequestParam String title, @RequestParam String content) {
milvusService.addDocument(title, content);
return "文档插入 Milvus 成功!";
}
/**
* 检索接口(小白可通过浏览器访问测试)
* 访问示例:GET http://localhost:8080/milvus/search?query=你喜欢什么运动&topK=5
*/
@GetMapping("/search")
public List<Document> search(@RequestParam String query, @RequestParam int topK) {
return milvusService.searchSimilar(query, topK);
}
}
5.3.5 启动类(Spring Boot 入口,必须有)
java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MilvusApplication {
public static void main(String[] args) {
// 启动 Spring Boot 项目,小白直接运行该类
SpringApplication.run(MilvusApplication.class, args);
}
}
5.4 Spring AI Alibaba 集成 Milvus(阿里生态首选)
5.4.1 Maven 依赖(复制到 pom.xml)
xml
<!-- Spring Boot 父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<!-- Spring Cloud Alibaba 版本管理(小白不要修改) -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-ai-alibaba-dependencies</artifactId>
<version>2024.0.0.0</version>
pom<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Cloud Alibaba AI 核心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-ai-alibaba-starter</artifactId>
</dependency>
<!-- Milvus 向量存储集成 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-ai-alibaba-vectorstore-milvus</artifactId>
</dependency>
<!-- 中文 Embedding 模型(BgeSmallZhV15) -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-ai-alibaba-embedding</artifactId>
</dependency>
<!-- Spring Web(用于测试接口) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
5.4.2 配置类(手动注册 Bean,小白复制即用)
java
import com.alibaba.cloud.ai.embedding.EmbeddingModel;
import com.alibaba.cloud.ai.embedding.bge.BgeSmallZhV15EmbeddingModel;
import com.alibaba.cloud.ai.vectorstore.milvus.MilvusVectorStore;
import com.alibaba.cloud.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MilvusAlibabaConfig {
/**
* 注册中文 Embedding 模型(BgeSmallZhV15,生成512维FLOAT_VECTOR)
*/
@Bean
public EmbeddingModel embeddingModel() {
return new BgeSmallZhV15EmbeddingModel();
}
/**
* 注册 Milvus 向量存储(手动配置,和前面示例一致)
*/
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
return MilvusVectorStore.builder()
.uri("http://127.0.0.1:19530") // Milvus 连接地址
.collectionName("alibaba_ai_collection") // 集合名,自定义
.dimension(512) // 向量维度,和模型一致
.vectorType("FLOAT_VECTOR") // 指定向量类型(密集向量)
.embeddingModel(embeddingModel) // 绑定 Embedding 模型
.build();
}
}
5.4.3 业务服务类(小白可直接复制)
java
import com.alibaba.cloud.ai.document.Document;
import com.alibaba.cloud.ai.vectorstore.SearchRequest;
import com.alibaba.cloud.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class MilvusAlibabaService {
private final VectorStore vectorStore;
// 构造器注入向量存储对象
public MilvusAlibabaService(VectorStore vectorStore) {
this.vectorStore = vectorStore;
}
/**
* 插入文档(小白调用示例:addDocument("我喜欢踢足球"))
*/
public void addDocument(String content) {
Document document = new Document(content);
vectorStore.add(List.of(document));
}
/**
* 相似检索(小白调用示例:search("你喜欢什么运动?", 5))
*/
public List<Document> search(String query, int topK) {
SearchRequest request = SearchRequest.builder()
.query(query)
.topK(topK)
.build();
return vectorStore.search(request);
}
}
六、企业级开发最佳实践与小白避坑指南
6.1 选型建议(小白直接抄,不用纠结)
| 场景 | 推荐方案 | 核心理由(小白版) |
|---|---|---|
| 生产环境、百万级以上向量 | Milvus 集群版 | 稳定、能存海量数据、支持扩展,企业都用它 |
| 原型验证、Demo 开发、万级以内向量 | Redis Stack | 部署简单、不用装多个组件,小白上手快 |
| Spring Boot 项目 | Spring AI / Spring AI Alibaba | 无缝集成 Spring 生态,不用手动配置,开发效率高 |
| 非 Spring 项目、灵活定制 | LangChain4j | 生态最全、功能最灵活,和你提供的代码最匹配 |
6.2 小白必避的坑(重点!避免踩雷)
-
向量维度不匹配(最常见错误)
-
错误:模型输出 512 维,Collection 配置 384 维,插入直接报错(dimension mismatch)
-
解决:先确认 Embedding 模型的输出维度(BgeSmallZhV15 是 512 维),再创建 Collection,创建后不可修改维度
-
-
Milvus 连接失败
-
错误:连接超时、拒绝连接(Connection refused)
-
排查步骤:
-
执行
docker-compose ps确认 3 个容器都是 Up 状态 -
执行
telnet 127.0.0.1 19530确认端口可访问 -
检查 URI 格式是否正确:必须是
http://ip:19530,不能少 http://
-
-
-
相似度得分理解错误
-
错误:以为所有度量算法都是"值越大越相似"
-
正确理解:
-
余弦相似度/IP:值越大越相似(0.9 比 0.1 更相似)
-
L2/汉明距离:值越小越相似(0.1 比 1.0 更相似)
-
-
-
检索不到结果
- 解决:增大 nprobe 参数(从 10 调到 50)、降低相似度阈值、用 Attu 确认数据已成功插入
6.3 生产环境注意事项(小白提前了解)
-
数据持久化:必须挂载本地目录到容器(docker-compose 中已配置),防止容器删除后数据丢失
-
权限控制:生产环境必须给 Milvus/Redis 设置用户名密码,禁止外网直接访问(避免被攻击)
-
监控告警:通过 Prometheus + Grafana 监控内存、CPU、检索延迟,设置告警阈值(比如内存占用>80%告警)
-
备份恢复:定期备份 etcd 元数据和 MinIO 数据,防止数据丢失
-
索引优化:百万级以上数据使用 HNSW 索引,平衡检索速度和精度(小白测试用默认索引即可)
七、常见问题排查速查表(小白速查,不用百度)
| 问题现象 | 常见原因 | 解决方法(小白可操作) |
|---|---|---|
插入向量报错 dimension mismatch |
向量维度和 Collection 配置不一致 | 1. 确认模型维度(BgeSmallZhV15=512);2. 删除旧 Collection,重新创建匹配维度的集合 |
| Milvus 服务启动失败 | etcd/MinIO 未正常启动 | 1. 查看容器日志 docker logs milvus-standalone;2. 重启 etcd/MinIO 服务(docker-compose restart etcd minio) |
| 检索结果为空 | 1. 数据未插入成功;2. nprobe 太小;3. 相似度阈值太高 | 1. Attu 查看 Collection 数据量;2. 增大 nprobe 到 50+;3. 降低相似度阈值 |