当前位置: 首页 > java >正文

Spring AI(6)——向量存储

向量数据库是一种特殊类型的数据库,在 AI 应用中发挥着至关重要的作用。

在向量数据库中,查询与传统关系型数据库不同。它们执行的是相似性搜索,而非精确匹配。当给定一个向量作为查询时,向量数据库会返回与该查询向量“相似”的向量。

Spring AI 通过 VectorStore 接口提供了一个抽象的 API,用于与向量数据库交互。

VectorStore接口中主要方法:

public interface VectorStore extends DocumentWriter {default String getName() {return this.getClass().getSimpleName();}// 向向量数据库写入数据void add(List<Document> documents);// 根据id删除数据void delete(List<String> idList);// 根据过滤表达式删除数据void delete(Filter.Expression filterExpression);default void delete(String filterExpression) { ... };// 进行相似度搜索List<Document> similaritySearch(String query);List<Document> similaritySearch(SearchRequest request);default <T> Optional<T> getNativeClient() {return Optional.empty();}
}

支持的向量数据库:

  • Azure Vector Search
  • Apache Cassandra
  • Chroma Vector Store
  • Elasticsearch Vector Store
  • GemFire Vector Store
  • MariaDB Vector Store
  • Milvus Vector Store
  • MongoDB Atlas Vector Store
  • Neo4j Vector Store
  • OpenSearch Vector Store
  • Oracle Vector Store
  • PgVector Store
  • Pinecone Vector Store
  • Qdrant Vector Store
  • Redis Vector Store
  • SAP Hana Vector Store
  • Typesense Vector Store
  • Weaviate Vector Store
  • SimpleVectorStore - 一个简单的持久化向量存储实现,适合教学目的。

SimpleVectorStore使用

注意:需要提前启动上篇博客中通过Ollama安装的嵌入模型

SimpleVectorStore将向量数据存储在内存中。

导入jar

        <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-vector-store</artifactId></dependency>

创建SimpleVectorStore对象

    @Beanpublic SimpleVectorStore vectorStore() {return SimpleVectorStore.builder(embeddingModel).build();}

创建对象时,将存储对象和嵌入模型进行关联。关于嵌入模型的使用,参考:

Spring AI(5)——通过嵌入模型进行数据的向量化处理-CSDN博客

向SimpleVectorStore对象中写入测试数据

本例中,创建Document对象时,三个参数分别为:文档id,文档内容,文档的元数据。

    @PostConstructpublic void init() {List<Document> documents = List.of(new Document("1", "今天天气不错", Map.of("country", "郑州", "date", "2025-05-13")),new Document("2", "天气不错,适合旅游", Map.of("country", "开封", "date", "2025-05-15")),new Document("3", "去哪里旅游好呢", Map.of("country", "洛阳", "date", "2025-05-15")));// 存储数据simpleVectorStore.add(documents);}

通过调试可以看出, SimpleVectorStore对象中存储的原始文档信息和向量化后的数据。

进行相似度搜索

根据字符串内容进行搜索

    @GetMapping("/store")public String store(String message) {// 相似度检索List<Document> list= simpleVectorStore.similaritySearch("旅游");System.out.println(list.size());System.out.println(list.get(0).getText());return "success";}

通过调试可以看到,对所有的数据进行向量的相似度计算,并进行打分,计算结果按照score的降序排列 。

根据元数据过滤器进行搜索

使用字符串设置搜索条件

例如:

  • "country == 'BG'"

  • "genre == 'drama' && year >= 2020"

  • "genre in ['comedy', 'documentary', 'drama']"

SearchRequest request = SearchRequest.builder().query("World").filterExpression("country == 'Bulgaria'").build();

使用Filter.Expression设置搜索条件

可以使用 FilterExpressionBuilder 创建 Filter.Expression 的实例。一个简单的示例如下:

FilterExpressionBuilder b = new FilterExpressionBuilder();
Expression expression = this.b.eq("country", "BG").build();

可以使用以下运算符构建复杂的表达式:

EQUALS: '=='
MINUS : '-'
PLUS: '+'
GT: '>'
GE: '>='
LT: '<'
LE: '<='
NE: '!='

可以使用以下运算符组合表达式:

AND: 'AND' | 'and' | '&&';
OR: 'OR' | 'or' | '||';

参考示例:

Expression exp = b.and(b.eq("genre", "drama"), b.gte("year", 2020)).build();

还可以使用以下运算符:

IN: 'IN' | 'in';
NIN: 'NIN' | 'nin';
NOT: 'NOT' | 'not';

参考示例:

Expression exp = b.and(b.in("genre", "drama", "documentary"), b.not(b.lt("year", 2020))).build();

测试案例: 

    @GetMapping("/store")public String store(String message) {// 相似度检索// List<Document> list = simpleVectorStore.similaritySearch("旅游");// 创建过滤器对象FilterExpressionBuilder b = new FilterExpressionBuilder();Filter.Expression filter = b.eq("country", "郑州").build();// Filter.Expression filter = b.and(b.eq("country", "郑州"), b.gte("date", "2025-05-15")).build();;// 创建搜索对象SearchRequest request = SearchRequest.builder().query("旅游") // 搜索内容.filterExpression(filter) // 指定过滤器对象.build();List<Document> list = simpleVectorStore.similaritySearch(request);System.out.println(list.size());System.out.println(list.get(0).getText());return "success";}

删除数据

    @GetMapping("/store2")public String store2(String message) {// 删除数据simpleVectorStore.delete(List.of("3"));return "success";}

注意:也可以根据元数据过滤器进行删除,本文不再演示

 Milvus进行向量存储

关于milvus的介绍和环境安装,参考:

LangChain4j(16)——使用milvus进行向量存储-CSDN博客

注意:需要提前启动上篇博客中通过Ollama安装的嵌入模型

导入jar 

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-vector-store-milvus</artifactId>
</dependency>

yml配置

在原来的基础上,增加如下配置:

spring:ai:vectorstore:milvus:client:host: "localhost"port: 19530databaseName: "myai"collectionName: "vector_store"embeddingDimension: 768indexType: IVF_FLATmetricType: COSINE

该配置中指定了milvus的数据库名,collection名称,向量纬度,索引的类型,向量搜索的算法等,更多的属性设置可以参考官网:

属性描述默认值

spring.ai.vectorstore.milvus.database-name

要使用的 Milvus 数据库名称。

default

spring.ai.vectorstore.milvus.collection-name

用于存储向量的 Milvus Collection 名称

vector_store

spring.ai.vectorstore.milvus.initialize-schema

是否初始化 Milvus 后端

false

spring.ai.vectorstore.milvus.embedding-dimension

存储在 Milvus Collection 中的向量维度。

1536

spring.ai.vectorstore.milvus.index-type

为 Milvus Collection 创建的索引类型。

IVF_FLAT

spring.ai.vectorstore.milvus.metric-type

用于 Milvus Collection 的度量类型(Metric Type)。

COSINE

spring.ai.vectorstore.milvus.index-parameters

用于 Milvus Collection 的索引参数。

{"nlist":1024}

spring.ai.vectorstore.milvus.id-field-name

Collection 的 ID 字段名称

doc_id

spring.ai.vectorstore.milvus.is-auto-id

布尔标志,指示 ID 字段是否使用 auto-id

false

spring.ai.vectorstore.milvus.content-field-name

Collection 的内容字段名称

content

spring.ai.vectorstore.milvus.metadata-field-name

Collection 的元数据字段名称

metadata

spring.ai.vectorstore.milvus.embedding-field-name

Collection 的嵌入字段名称

embedding

spring.ai.vectorstore.milvus.client.host

主机名称或地址。

localhost

spring.ai.vectorstore.milvus.client.port

连接端口。

19530

spring.ai.vectorstore.milvus.client.uri

Milvus 实例的 URI

-

spring.ai.vectorstore.milvus.client.token

用作身份识别和认证目的的 Token。

-

spring.ai.vectorstore.milvus.client.connect-timeout-ms

客户端通道的连接超时值。超时值必须大于零。

10000

spring.ai.vectorstore.milvus.client.keep-alive-time-ms

客户端通道的 Keep-alive 时间值。Keep-alive 值必须大于零。

55000

spring.ai.vectorstore.milvus.client.keep-alive-timeout-ms

客户端通道的 Keep-alive 超时值。超时值必须大于零。

20000

spring.ai.vectorstore.milvus.client.rpc-deadline-ms

愿意等待服务器回复的截止时间。设置截止时间后,客户端在遇到由网络波动引起的快速 RPC 失败时将等待。截止时间值必须大于或等于零。

0

spring.ai.vectorstore.milvus.client.client-key-path

用于 TLS 双向认证的 client.key 路径,仅当 "secure" 为 true 时生效

-

spring.ai.vectorstore.milvus.client.client-pem-path

用于 TLS 双向认证的 client.pem 路径,仅当 "secure" 为 true 时生效

-

spring.ai.vectorstore.milvus.client.ca-pem-path

用于 TLS 双向认证的 ca.pem 路径,仅当 "secure" 为 true 时生效

-

spring.ai.vectorstore.milvus.client.server-pem-path

用于 TLS 单向认证的 server.pem 路径,仅当 "secure" 为 true 时生效。

-

spring.ai.vectorstore.milvus.client.server-name

设置 SSL 主机名检查的目标名称覆盖,仅当 "secure" 为 True 时生效。注意:此值会传递给 grpc.ssl_target_name_override

-

spring.ai.vectorstore.milvus.client.secure

保护此连接的授权,设置为 True 以启用 TLS。

false

spring.ai.vectorstore.milvus.client.idle-timeout-ms

客户端通道的空闲超时值。超时值必须大于零。

24h

spring.ai.vectorstore.milvus.client.username

此连接的用户名和密码。

root

spring.ai.vectorstore.milvus.client.password

此连接的密码。

milvus

通过attu创建collection

注意:collection中的字段名称使用的是上面属性中的默认名称:

spring.ai.vectorstore.milvus.id-field-name=doc_id

spring.ai.vectorstore.milvus.content-field-name=content
spring.ai.vectorstore.milvus.metadata-field-name=metadata
spring.ai.vectorstore.milvus.embedding-field-name=embedding

注入MilvusVectorStore对象

    @Resourceprivate MilvusVectorStore milvusVectorStore;

添加测试数据

    @PostConstructpublic void init() {List<Document> documents = List.of(new Document("今天天气不错", Map.of("country", "郑州", "date", "2025-05-13")),new Document("天气不错,适合旅游", Map.of("country", "开封", "date", "2025-05-15")),new Document("去哪里旅游好呢", Map.of("country", "洛阳", "date", "2025-05-15")));// 存储数据milvusVectorStore.add(documents);}

本例没有指定Document的id,id会随机生成

相似度搜索

    @GetMapping("/search")public String search(String message) {// 相似度检索List<Document> list = milvusVectorStore.similaritySearch("旅游");System.out.println(list.size());System.out.println(list.get(0).getText());return "success";}@GetMapping("/search5")public String search5(String message) {MilvusSearchRequest request = MilvusSearchRequest.milvusBuilder().query("旅游").topK(5).similarityThreshold(0.7).filterExpression("date == '2025-05-15'") // Ignored if nativeExpression is set//.searchParamsJson("{\"nprobe\":128}").build();// 相似度检索List<Document> list = milvusVectorStore.similaritySearch(request);System.out.println(list.size());System.out.println(list.get(0).getText());return "success";}

top_k: 表示根据token排名,只考虑前k个token

similarity threshold:相似度的阈值

http://www.xdnf.cn/news/6392.html

相关文章:

  • mongodb处理时区转换问题
  • 论云原生架构及其应用~系统架构师论文
  • 前端ECS简介
  • Java爬虫能处理京东商品数据吗?
  • 什么是Baklib数字化内容管理?
  • [Mamba轻量化]DefMamba: Deformable Visual State Space Model,CVPR2025
  • 如何在线免费压缩PDF文档?
  • Unix Bourne Shell
  • ET MailBoxComponent类(实体) 分析
  • 开源的跨语言GUI元素理解8B大模型:AgentCPM-GUI
  • html的鼠标点击事件有哪些写法
  • 密码学实验:凯撒密码
  • JESD204 ip核使用与例程分析(一)
  • PINN Poisson 1d
  • Vue3学习(组合式API——reactive()和ref()函数详解)
  • 基于大模型预测短暂性脑缺血发作(TIA)的技术方案大纲
  • aptitude 深度教程:从基础到生产实践
  • 紫外相机工作原理及可应用范围
  • 海外短剧系统:解锁全球内容消费新蓝海
  • mysql-Java手写分布式事物提交流程
  • RHCSA 考试操作手册(基于红帽企业 Linux 8/9 版本)​
  • AbstractErrorController简介-笔记
  • Flink 运维监控与指标采集实战(Prometheus + Grafana 全流程)
  • 人工智能、深度学习、机器学习的联系与区别
  • JMeter元件(元组)--简单介绍
  • 群晖NAS部署PlaylistDL音乐下载器结合cpolar搭建私有云音乐库
  • 基于Leaflet和天地图的免费运动场所WebGIS可视化-以长沙市为例
  • 嘉立创天猛星使用串口下载代码
  • 精益数据分析(61/126):移情阶段评分体系构建与实战案例解析
  • 解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs-MCP大模型上下文解析