Spring AI:文档向量化存储与检索
Spring AI:文档向量化存储与检索
历史文章
Spring AI:对接DeepSeek实战
Spring AI:对接官方 DeepSeek-R1 模型 —— 实现推理效果
Spring AI:ChatClient实现对话效果
Spring AI:使用 Advisor 组件 - 打印请求大模型出入参日志
Spring AI:ChatMemory 实现聊天记忆功能
Spring AI:本地安装 Ollama 并运行 Qwen3 模型
Spring AI:提示词工程
Spring AI:提示词工程 - Prompt 角色分类(系统角色与用户角色)
Spring AI:基于 “助手角色” 消息实现聊天记忆功能
Spring AI:结构化输出 - 大模型响应内容
Spring AI:Docker 安装 Cassandra 5.x(限制内存占用)&& CQL
Spring AI:整合 Cassandra - 实现聊天消息持久化
Spring AI:多模态 AI 大模型
Spring AI:文生图:调用通义万相 AI 大模型
Spring AI:文生音频 - cosyvoice-V2
Spring AI:文生视频 - wanx2.1-i2v-plus
Spring AI:上手体验工具调用(Tool Calling)
Spring AI:整合 MCP Client - 调用高德地图 MCP 服务
Spring AI:搭建自定义 MCP Server:获取 QQ 信息
Spring AI:对接自定义 MCP Server
Spring AI:RAG 增强检索介绍
Spring AI:Docker 安装向量数据库 - Redis Stack
上文中,我们已经在本地环境中,将 Redis 向量数据库安装好了。本文中,我们尝试将一些文档,通过 “向量模型” 进行向量化处理,并存储到 Redis 数据库中,最后通过关键词进行检索,看看能否将相似的文档检索出来。
新建项目
新建一个Spring Boot项目,xiaoma-vector-store-search
①:选择 Spring Boot 生成器来创建项目;
②:项目名称填写 xiaoma-vector-store-search;
③: 项目存放位置,选择之前创建好的文件夹;
④:项目构建方式选择 Maven;
⑤:填写 Group 组织名称,通常为公司域名倒写,如 com.xiaoma;
⑥: 项目唯一标识符,这里填写 xiaoma-vector-store-search;
⑦: 包名填写 com.xiaoma.vector.store;
⑧: JDK 版本选择 21 版本;
⑨: Java 语言版本也选择 21, 和 JDK 保持一致;
修改 pom
接着,编辑 pom.xml 文件,首先将 Spring Boot 的版本号修改为 3.4.5。另外,添加 Spring AI 框架的依赖管理、 lombok 工具依赖、仓库地址等,如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xiaoma</groupId>
<artifactId>xiaoma-vector-store-search</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>xiaoma-vector-store-search</name>
<description>向量存储与检索</description>
<properties>
<!-- JDK 版本 -->
<java.version>21</java.version>
<!-- Spring AI 版本 -->
<spring-ai.version>1.0.0</spring-ai.version>
<lombok.version>1.18.30</lombok.version>
</properties>
<!-- Spring AI 依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 避免编写那些冗余的 Java 样板式代码,如 get、set 方法等 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<name>Central Portal Snapshots</name>
<id>central-portal-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<!-- 添加华为云、阿里云 maven 中央仓库,提升 Jar 包下载速度 -->
<repository>
<id>huaweicloud</id>
<name>huawei</name>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</repository>
<repository>
<id>aliyunmaven</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
</project>
选择向量模型
我们需要先挑选一个 “向量模型”,它够将文本、图像、视频等数据转换为数学空间中的向量。通过计算向量之间的距离或夹角,可以量化数据的相似度,从而作用于精准搜索、智能推荐、自动分类及异常检测等任务。
登陆到 “阿里百炼 ” 的模型广场,筛选 “向量模型” 分类下所有大模型,如下图所示:

这里我们选择最新的 “通用文本向量-v4” 模型,点击 “API参考”,可以知道此模型的具体名称为 text-embedding-v4 , 将其复制出来。
添加依赖
<!-- OpenAI -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<!-- 整合向量数据库 Redis -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-vector-store-redis</artifactId>
</dependency>
记得刷新一下 pom.xml 文件,将依赖下载到本地 Maven 仓库中。
添加配置
添加文件application.yml
然后,将 application.properties 重命名为 application.yml,添加配置项如下,包括 Redis 链接、阿里百炼接入配置、使用的哪个向量模型、以及向量数据库的相关设置:
server:
port: 8090 # 项目启动端口
spring:
data:
redis:
host: localhost # Redis URL 链接
port: 6379 # Redis 端口
ai:
openai:
base-url: https://dashscope.aliyuncs.com/compatible-mode # OpenAI 服务的访问地址,这里使用的是阿里云百炼
api-key: xxx # 填写阿里百炼的 API Key, 改成你自己的
embedding:
options:
model: text-embedding-v4 # 向量模型
vectorstore:
redis:
initialize-schema: true # 是否初始化模式
index-name: xiaoma-ai-index # 自定义索引名称
prefix: embedding # 自定义键名前缀
文档向量化处理,并存入 Redis
接着,在后端项目中新建一个 /runner 包,并新建一个 InitEmbeddingIndexRunner 启动任务,用于在项目刚启动时,将 3 条文档进行向量化处理,并存储到 Redis 中:
@Component
public class InitEmbeddingIndexRunner implements ApplicationRunner {
@Resource
private VectorStore vectorStore;
@Override
public void run(ApplicationArguments args) {
// 定义 3 条文档
List<Document> documents = List.of(
new Document("冰箱首次使用指南:拆箱后静置24小时再通电,调节温控器至4℃冷藏室、-18℃冷冻室。清洁内胆时请使用中性洗涤剂。",
Map.of("章节", "安全须知", "版本", "2025")),
new Document("节能技巧:避免频繁开关门,热食冷却后再放入,定期除霜可提升制冷效率。建议每月清洁一次冷凝器。"),
new Document("故障代码手册:E1温度传感器异常,E2化霜故障,F1通讯错误。遇到E2代码请断电2小时后重启,若持续出现需联系售后。",
Map.of("章节", "故障处理", "紧急程度", "高"))
);
// 通过向量模型,将文档向量化存储到 Redis 中
vectorStore.add(documents);
}
}
测试
重启后端项目,观察控制台日志,确保启动没有任何报错:
然后,查看 Redis 数据库,如下图所示,不出意外,3条文档的向量化数据已经存储成功了:

检索向量数据库
接下来,我们再新建一个 /controller 包,并新建 VectorSearchController 控制器,声明 /vector/search 接口,用于根据对应关键词来检索向量数据库,代码如下:
@RestController
@RequestMapping("/vector")
public class VectorSearchController {
@Resource
private VectorStore vectorStore;
/**
* 检索向量数据库
* @param key
* @return
*/
@GetMapping(value = "/search")
public List<Document> search(@RequestParam(value = "key") String key) {
// 检索与查询相似的文档
List<Document> results = vectorStore.similaritySearch(SearchRequest.builder()
.query(key) // 查询的关键词
.topK(2) // 查询相似度最高的 2 条文档
.build());
return results;
}
}
测试
重启后端项目,浏览器请求地址 http://localhost:8090/vector/search?key=冰箱第一次使用,看看能否检索出与关键词 “冰箱第一次使用” 匹配度高的文档。

可以看到返回的结果中,是相似度较高的文档,不过,返回了两条一摸一样的文档,这是怎么回事呢?这是因为我们启动了两次后端项目,导致 Runnner 初始化任务执行了 2 次,导致重复添加了一次文档。刷新一下 Redis 数据,也可以看到目前有 6 条数据,所以,返回 2 条是正常的!
更多推荐
所有评论(0)