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.mzph.cn/diannao/83260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt功能区:简介与安装

Qt功能区 1. 功能区简介2. SARibbon2.1 简介2.2 编译与安装采用CMake-gui进行编译采用VS进行编译安装与使用 Qt 官方不支持 Ribbon 风格&#xff08;Ribbon UI 风格是微软开创的&#xff0c;具有专利许可协议&#xff0c;许可协议对从构建 UI 的指令到每个按钮间的空格数都做了…

iOS safari和android chrome开启网页调试与检查器的方法

手机开启远程调试教程&#xff08;适用于 Chrome / Safari&#xff09; 前端移动端调试指南&#xff5c;适用 iPhone 和 Android&#xff5c;WebDebugX 出品 本教程将详细介绍如何在 iPhone 和 Android 手机上开启网页检查器&#xff0c;配合 WebDebugX 实现远程调试。教程包含…

Golang企业级商城高并发微服务实战

Golang企业级商城高并发微服务实战包含内容介绍&#xff1a; 从零开始讲了百万级单体高并发架构、千万级微服务架构&#xff0c;其中包含Rpc实现微服务、微服务的跨语言调用jsonrpc和protobuf、protobuf的安装、protobuf高级语法、protobuf结合Grpc实现微服务实战、微服务服务…

实现可靠的 WebSocket 连接:心跳与自动重连的最佳实践

概览 本文将手把手教你如何从零编写一个可用于直播或在线聊天的 WSocket 类&#xff0c;依次实现连接建立、心跳检测、断线重连、消息收发以及资源清理等功能。我们将结合 WebSocket API 的标准用法、心跳保持 和 重连策略&#xff0c;并充分运用现代 JavaScript 语法&#xf…

UEFI Spec 学习笔记---33 - Human Interface Infrastructure Overview(1)

33 - Human Interface Infrastructure Overview 本章节主要用于介绍Human Interface Infrastructure&#xff08;HII&#xff09;架构介绍&#xff0c;描述如何通过 HII 来管理用户的输入&#xff0c;以及描述在 UEFI spec 中涉及 HII 相关的 Protocol、function 和类型定义。…

ip命令详解

控制网卡的硬件状态 ip link set ens36 down ip link set ens36 up 修改网卡名称&#xff08;临时&#xff09; ip link set ens36 down ip link set ens36 name xxx 修改网卡的mac地址 ip link set ens36 down ip link set xxx name ens36 查看ip的addr ip addr show ip ad…

hadoop中了解yarm

Hadoop中的YARN&#xff08;Yet Another Resource Negotiator&#xff09;是一种新的Hadoop资源管理器&#xff0c;是一个通用资源管理系统&#xff0c;可为上层应用提供统一的资源管理和调度。以下是其相关介绍&#xff1a; 核心思想 将JobTracker的资源管理和作业调度/监控功…

做好的QT软件,换一个笔记本打开后发现字体很小,部分字体还被控件遮挡

出现这种情况的原因主要是屏幕的DPI&#xff08;每英寸点数&#xff09;不同。Qt中控件的大小单位为像素&#xff0c;在高DPI下&#xff0c;控件会变小&#xff0c;低DPI下控件会变大。而Qt中字体的单位默认为磅&#xff0c;无论在什么显示器上显示同一磅值的字体&#xff0c;其…

linux - 权限的概念

目录 用户权限 超级用户与普通用户的区别 超级用户&#xff08;root&#xff09;&#xff1a; 普通用户&#xff1a; 切换用户身份 使用sudo执行高权限命令 用户管理 用户组管理 文件权限 文件访问者类别 基本权限 权限表示方法 权限修改 chmod chown chgrp u…

Python函数返回值的艺术:为何True/False是更优实践及例外情况分析

在Python编程实践中&#xff0c;子程序的返回值设计往往是一个容易被忽视但却至关重要的设计决策。本文将深入探讨为什么返回True/False往往是更好的选择&#xff0c;何时应该避免这种做法&#xff0c;以及如何处理与None值相关的问题。 为什么返回True/False是更好的实践&…

STM32单片机内存分配详细讲解

单片机的内存无非就两种&#xff0c;内部FLASH和SRAM&#xff0c;最多再加上一个外部的FLASH拓展。在这里我以STM32F103C8T6为例子讲解FLASH和SRAM。 STM32F103C8T6具有64KB的闪存和20KB的SRAM。 一. Flash 1.1 定义 非易失性存储器&#xff0c;即使在断电后&#xff0c;其所…

【Tools】Visual Studio使用经验介绍(包括基本功能、远程调试、引入第三方库等等)

这里写目录标题 1. VS基本使用1.1. 快捷键1.2. 查看变量地址1.3. 查看代码汇编1.4. visual studio 热重载功能的使用1.5. vs远程服务器调试1.6. 引入第三方库VLD1.7. release debug模式 1. VS基本使用 1.1. 快捷键 ctrl c :复制光标所在行 注意&#xff1a;只需要光标在这…

网络爬虫学习之httpx的使用

开篇 本文整理自《Python3 网络爬虫实战》&#xff0c;主要是httpx的使用。 笔记整理 使用urllib库requests库的使用&#xff0c;已经可以爬取绝大多数网站的数据&#xff0c;但对于某些网站依然无能为力。 这是因为这些网站强制使用HTTP/2.0协议访问&#xff0c;这时urllib和r…

Python内存管理:赋值、浅拷贝与深拷贝解析

赋值与共享资源 在Python中&#xff0c;直接赋值操作&#xff08;如 list2 list1&#xff09;会导致两个变量共享同一个内存地址。这意味着对 list1 的修改会直接影响到 list2&#xff0c;因为它们指向同一个对象。 注意: 赋值等于完全共享资源 如果我们不希望这样完全共享&…

CentOS7原有磁盘扩容实战记录(LVM非LVM)【针对GPT分区】

一、环境 二、命令及含义 fdisk ‌ ‌ fdisk‌是一个较老的分区表创建和管理工具&#xff0c;主要支持MBR&#xff08;Master Boot Record&#xff09;格式的分区表。MBR分区表支持的硬盘单个分区最大容量为2TB&#xff0c;最多可以有4个主分区。fdisk通过命令行界面进行操…

获取相机图像(ROS2)

文章目录 前言一、获取笔记本自带相机图像1.打开终端2.安装usb-cam功能包3.启动相机节点4.再打开一个终端5.启动rqt查看图像(1)方法一&#xff1a;点击窗口选项&#xff0c;打开图像话题(2)方法二&#xff1a;使用命令行&#xff0c;直接打开图像话题 二、获取USB相机图像总结 …

Go 语言中接口类型转换为具体类型

类型转换方法 在 Go 语言中&#xff0c;将接口类型转换为具体类型主要有以下几种方法&#xff1a; 1. 类型断言&#xff08;Type Assertion&#xff09; var i interface{} "hello"// 基本形式 s : i.(string) // 将接口i转换为string类型 fmt.Println(s) // 输…

ES C++客户端安装及使用

介绍 Elasticsearch &#xff0c; 简称 ES &#xff0c;它是个开源分布式搜索引擎&#xff0c;它的特点有&#xff1a;分布式&#xff0c;零配置&#xff0c;自动发现&#xff0c;索引自动分片&#xff0c;索引副本机制&#xff0c;restful 风格接口&#xff0c;多数据源&…

力扣-94.二叉树的中序遍历

题目描述 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 class Solution { public:void inorder(TreeNode* root, vector<int>& res){//C这里&一定要加if(!root)return;inorder(root->left,res);res.push_back(root->val);inorder(ro…

《大模型微调实战:Llama 3.0全参数优化指南》

全参数微调&#xff08;Full Parameter Fine-Tuning&#xff09;是推动大模型适应垂直领域任务的核心技术&#xff0c;尤其对于Llama 3.0这类千亿级参数模型而言&#xff0c;其性能优化与场景适配能力直接决定了实际应用价值。然而&#xff0c;全参数微调面临计算成本高、内存占…