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:相似度的阈值
相关文章:

Spring AI(6)——向量存储
向量数据库是一种特殊类型的数据库,在 AI 应用中发挥着至关重要的作用。 在向量数据库中,查询与传统关系型数据库不同。它们执行的是相似性搜索,而非精确匹配。当给定一个向量作为查询时,向量数据库会返回与该查询向量“相似”的…...
Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解
Spring Data Elasticsearch 中 ElasticsearchOperations 构建查询条件的详解 前言一、引入依赖二、配置 Elasticsearch三、创建模型类(Entity)四、使用 ElasticsearchOperations 进行 CRUD 操作1. 保存数据(Create)2. 获取数据&am…...
react-router基本写法
1. 创建项目并安装所有依赖 npx create-react-app react-router-pro npm i 2. 安装所有的 react router 包 npm i react-router-dom 3. 启动项目 npm run start router/index.js // 创建路由实例 绑定path elementimport Layout from "/pages/Layout"; import…...

【Matlab】最新版2025a发布,深色模式、Copilot编程助手上线!
文章目录 一、软件安装1.1 系统配置要求1.2 安装 二、新版功能探索2.1 界面图标和深色主题2.2 MATLAB Copilot AI助手2.3 绘图区升级2.4 simulink2.5 更多 延迟一个月,终于发布了🤭。 一、软件安装 1.1 系统配置要求 现在的电脑都没问题,老…...
智能语音助手的未来:从交互到融合
摘要 随着人工智能技术的不断进步,智能语音助手已经成为我们生活中不可或缺的一部分。从简单的语音指令到复杂的多模态交互,语音助手正在经历一场深刻的变革。本文将探讨智能语音助手的发展历程、当前的技术瓶颈以及未来的发展方向,特别是其在…...

uniapp,小程序中实现文本“展开/收起“功能的最佳实践
文章目录 示例需求分析实现思路代码实现1. HTML结构2. 数据管理3. 展开/收起逻辑4. CSS样式 优化技巧1. 性能优化2. 防止事件冒泡3. 列表更新处理 实际效果总结 在移动端应用开发中,文本内容的"展开/收起"功能是提升用户体验的常见设计。当列表项中包含大…...

思维链框架:LLMChain,OpenAI,PromptTemplate
什么是思维链,怎么实现 目录 什么是思维链,怎么实现思维链(Chain of Thought)在代码中的实现方式1. 手动构建思维链提示2. 少样本思维链提示3. 自动思维链生成4. 思维链与工具使用结合5. 使用现有思维链框架:LLMChain,OpenAI,PromptTemplate思维链实现的关键要点思维链(C…...
HOT100 (哈希双指针)
哈希 1.两数之和(unordered_map) 给定一个整数数组 nums 和一个整数目标值 target,返回满足条件的数组下标 思路:用umap,一边遍历,一边装; class Solution {public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> u…...

使用 QGIS 插件 OpenTopography DEM Downloader 下载高程数据(申请key教程)
使用 QGIS 插件 OpenTopography DEM Downloader 下载高程数据 目录 使用 QGIS 插件 OpenTopography DEM Downloader 下载高程数据📌 简介🛠 插件安装方法🌍 下载 DEM 数据步骤🔑 注册 OpenTopography 账号(如使用 Cope…...

计算机组成与体系结构:替换策略(MRU LRU PLRU LFU)
目录 🎲 MRU(最近最常使用) 🪜 操作流程: 🎲 LRU(最近最少使用) 🪜 操作流程: 示例 🔍 Age Bits(年龄位) 核心思想…...

websocket入门详解
入门websocket的基础应该掌握一下问题: 1、什么是握手? 2、什么是websocket? 3、websocket和http的区别,应用场景 4、html前端简单代码演示 5、springboot整合websocket使用 6、使用vueelementui打造简单聊天室 7、使用web…...
《数字藏品社交化破局:React Native与Flutter的创新实践指南》
NFT,这种非同质化代币,赋予了数字资产独一无二的身份标识,从数字艺术作品到限量版虚拟物品,每一件NFT数字藏品都承载着独特的价值与意义。当React Native和Flutter这两大跨平台开发框架遇上NFT数字藏品,一场技术与创意…...

(6)python开发经验
文章目录 1 QListWidget样式显示异常2 模块编码错误3 qtcreator开发pyqt编码错误 更多精彩内容👉内容导航 👈👉Qt开发 👈👉python开发 👈 1 QListWidget样式显示异常 main.py import sys from PySide6.QtWi…...

HPC软件使用之ANSYS Fluent
目录 一、软件介绍 二、脚本编写 2.1 jou文件 2.2 slurm脚本文件 三、作业提交及查看 四、案例演示 4.1 网格模型 4.2 jou脚本 4.3 slurm脚本 4.4 计算 4.5 结果查看 从本文开始,我们将介绍如何在超级计算机上使用科学计算、工程仿真计算软件开展计算&am…...

YOLO11解决方案之距离计算探索
概述 Ultralytics提供了一系列的解决方案,利用YOLO11解决现实世界的问题,包括物体计数、模糊处理、热力图、安防系统、速度估计、物体追踪等多个方面的应用。 测量两个物体之间的间距被称为特定空间内的距离计算,YOLO11使用两个边界框的中心…...

论文学习_Precise and Accurate Patch Presence Test for Binaries
摘要:打补丁是应对软件漏洞的主要手段,及时将补丁应用到所有受影响的软件上至关重要,然而这一点在实际中常常难以做到,研究背景。因此,准确检测安全补丁是否已被集成进软件发行版本的能力,对于防御者和攻击…...

Ascend的aclgraph(九)AclConcreteGraph:e2e执行aclgraph
1回顾 前面的几章内容探讨了aclgraph运行过程中的涉及到的关键模块和技术。本章节将前面涉及到的模块串联起来,对aclgraph形成一个端到端的了解。 先给出端到端运行的代码,如下: import torch import torch_npu import torchair import log…...
JSX语法介绍
文章目录 JSX介绍JSX的引入JSX的全称babel转换工具 JSX的基本语法创建组件的第一种方式创建组件父组件传值给子组件 class 关键字的介绍class的基本用法:使用class创建对象使用 class 实现 JS 中的继承 创建组件的第二种方式:使用 class 关键字父组件传值…...
增强 HTNN 服务网格功能:基于 Istio 的BasicAuth 与 ACL 插件开发实战
目录 1.引言 什么是HTNN? 为什么开发 BasicAuth 和 ACL 插件? 2.技术背景 技术栈概览 Istio 与服务网格简述 HTNN 框架与插件机制概览 3.插件开发详解:BasicAuth 与 ACL 3.1 BasicAuth插件 功能点 实现细节 3.2 ACL插件 功能点 …...

c++从入门到精通(四)--动态内存,模板与泛型编程
文章目录 动态内存直接管理内存Shared_ptr类Unique_ptrWeak_ptr动态数组allocator类文本查询程序 模板与泛型编程定义模板函数模板类模板模板参数成员模板控制实例化 模板实参推断重载与模板可变参数模板模板特例化 动态内存 c中动态内存的管理是通过new和delete运算符来实现的…...
C盘清理秘籍:快速提升系统性能
C盘清理的重要性 C盘作为系统盘,存储着操作系统和关键程序文件。随着使用时间的增加,C盘空间会逐渐被占用,导致系统运行缓慢、程序启动延迟等问题。定期清理C盘可以有效提升系统性能,延长硬盘寿命。 清理临时文件 Windows系统在…...
从 Vue3 回望 Vue2:组件设计升级——Options API vs Composition API
文章目录 从 Vue3 回望 Vue2:组件设计升级——Options API vs Composition API1、组件范式:框架设计思想的投影2、Vue2:Options API 的结构与局限结构清晰:新手友好、职责分明核心痛点:逻辑分散,难以聚合复…...

寻找两个正序数组的中位数 - 困难
************* Python topic: 4. 寻找两个正序数组的中位数 - 力扣(LeetCode) ************* Give the topic an inspection. Do the old topic will give you some new sparks. Before that, I do some really good craetive things about my logo. …...

国产密码新时代!华测国密 SSL 证书解锁安全新高度
在数字安全被提升到国家战略高度的今天,国产密码算法成为筑牢网络安全防线的关键力量。华测国密SSL证书凭借其强大性能与贴心服务,为企业网络安全保驾护航,成为符合国家安全要求的不二之选! 智能兼容,告别浏览器适配…...

【金仓数据库征文】从云计算到区块链:金仓数据库的颠覆性创新之路
目录 一、引言 二、金仓数据库概述 2.1 金仓数据库的背景 2.2 核心技术特点 2.3 行业应用案例 三、金仓数据库的产品优化提案 3.1 性能优化 3.1.1 查询优化 3.1.2 索引优化 3.1.3 缓存优化 3.2 可扩展性优化 3.2.1 水平扩展与分区设计 3.2.2 负载均衡与读写分离 …...
互联网大厂Java求职面试:AI与大模型集成的云原生架构设计
互联网大厂Java求职面试:AI与大模型集成的云原生架构设计 引言 在现代互联网企业中,AI与大模型技术的应用已经成为不可或缺的一部分。特别是在短视频平台、电商平台和金融科技等领域,如何高效地将大模型集成到现有的云原生架构中是一个巨大…...

股指期货套期保值怎么操作?
股指期货套期保值就是企业或投资者通过持有与其现货市场头寸相反的期货合约,来对冲价格风险的一种方式。换句话说,就是你在股票市场上买了股票(现货),担心股价下跌会亏钱,于是就在期货市场上卖出相应的股指…...

基于IBM BAW的Case Management进行项目管理示例
说明:使用IBM BAW的难点是如何充分利用其现有功能根据实际业务需要进行设计,本文是示例教程,因CASE Manager使用非常简单,这里重点是说明如何基于CASE Manager进行项目管理,重点在方案设计思路上,其中涉及的…...

黑马k8s(七)
1.Pod介绍 查看版本: 查看类型,这里加s跟不加s没啥区别,可加可不加 2.Pod基本配置 3.镜像拉去策略 本地没有这个镜像,策略是Never,启动失败 查看拉去策略: 更改拉去策略: 4.启动命令 运行的是nginx、busv…...

九、HQL DQL七大查询子句
作者:IvanCodes 日期:2025年5月15日 专栏:Hive教程 Apache Hive 的强大之处在于其类 SQL 的查询语言 HQL,它使得熟悉 SQL 的用户能够轻松地对存储在大规模分布式系统(如 HDFS)中的数据进行复杂的查询和分析…...