Spring AI 使用 Elasticsearch 作为向量数据库

前言

嗨,大家好,我是雪荷,最近在公司开发 AI 知识库,同时学到了一些 AI 开发相关的技术,这期先与大家分享一下如何用 ES 当做向量数据库。

安装ES

第一步我们先安装 Elasticsearch,这里建议 Elasticsearch 一定要在 8.13.x 以上,这里我选用的版本为 8.14.3。

下载 Docker Desktop

我使用 Docker 部署的 ES,所以需要先安装 Docker Desktop,大家根据自己的系统下载。

Mac 安装 Docker Desktop:Docker—苹果Mac安装Docker的两种方式-CSDN博客

Windows 安装 Docker Desktop:https://zhuanlan.zhihu.com/p/441965046

启动 ES

打开命令行直接一条命令梭哈,ES 自从 8.0 版本就默认开启安全认证了,这里我设置了关闭。

image-20250716215116133

docker run -d \--name elasticsearch \-p 9200:9200 -p 9300:9300 \-e "discovery.type=single-node" \-e "xpack.security.enabled=false" \-e "xpack.security.http.ssl.enabled=false" \elasticsearch:8.14.3

访问 http://localhost:9200,出现以下界面代表 ES 启动成功。

image-20250716215136310

部署本地大模型

前往 ollama 官网下载大模型本地部署工具,依旧根据自己系统进行选择。

image-20250716220233449

下载完毕通过命令行下载大模型,大家可以根据电脑配置和需求下载不同的模型和模型参数,qwen、deepseek 都是可以的,我这里就是 8b 的 deepseek-r1

ollama run deepseek-r1:8b

image-20250716220427770

然后还要部署一个文本嵌入模型,主要将文本转为向量化,这个模型仅 pull 就好,因为不是文本生成模型 run 不了。

ollama pull mxbai-embed-large:latest

搭建 Spring Boot 项目

搭建 Spring Boot 就不用我教了吧,相信各位佐助都会,建议 Spring Boot 版本要在 3.3.x 以上,我的为 3.5.3。

引入依赖

添加配置类

ES 配置类,主要配置 ES 连接地址、端口和向量数据的相关参数。

@Configuration
public class EsRagConfig {@Beanpublic RestClient restClient() {return RestClient.builder(new HttpHost("localhost", 9200, "http")) // 配置 ES 地址和端口.build();}@Beanpublic VectorStore vectorStore(RestClient restClient, EmbeddingModel embeddingModel) {ElasticsearchVectorStoreOptions options = new ElasticsearchVectorStoreOptions();options.setIndexName("custom-index"); // 设置索引名称options.setSimilarity(SimilarityFunction.cosine);options.setDimensions(1024); // 设置向量维度return ElasticsearchVectorStore.builder(restClient, embeddingModel).options(options).initializeSchema(true) // 没有索引时自动创建索引.batchingStrategy(new TokenCountBatchingStrategy()).build();}}

Ollama 配置类

将本地大模型注册为 Spring Bean,以后通过 ChatClient 来调用,这样更加自由、定制化。

@Configuration
public class OllamaConfig {@Resourceprivate ChatModel ollamaChatModel;@Resourceprivate LoggerAdvisor loggerAdvisor;@Beanpublic ChatClient chatClient() {return ChatClient.builder(ollamaChatModel).defaultAdvisors(loggerAdvisor).build();}}

排除自动配置类

在 Spring Boot类上排除 Elasticsearch 向量存储的自动配置类,不然会打架。

配置文件和知识库文件

主要指定 ollama 地址和本地模型,以及端口号和请求前缀

spring:ai:ollama:base-url: http://localhost:11434chat:model: deepseek-r1:8b
server:address: 0.0.0.0port: 8888servlet:context-path: /api

添加 Markdown 读取工具和 Markdown 文件

在 resources 目录放一个要存到向量数据库的文件。

image-20250716223134562

Markdown 文件内容如下:

image-20250716225147974

新建一个 RagController

@RestController
@RequestMapping("/rag")
public class RagController implements CommandLineRunner {@Resourceprivate ChatClient chatClient;@Resourceprivate ElasticsearchVectorStore vectorStore;@Resourceprivate MyMarkdownReader myMarkdownReader;@Overridepublic void run(String... args) throws Exception {List<Document> documents = myMarkdownReader.loadMarkdown();vectorStore.add(documents);System.out.println("文档写入 ES 成功");}@GetMapping("/completion")public String completion(@RequestParam String question) {return chatClient.prompt().user(question).advisors(new QuestionAnswerAdvisor(vectorStore)).call().content();}}
到这基本就 OK 了,随后启动项目,查看文件已经写入成功没,再通过 ES 调接口,查看是不是真的存储成功,可以看到真的成了。

image-20250716223208461

image-20250716224214356

调用结果如下:

image-20250716224152260

总结

本文只是实现的一个小 demo,适合小文本场景,对于大文本场景通常需要 ETL (提取

转换和加载)、token 切分,Rag 相似度匹配,条件过滤,而对于有图片的文件还需要实现 OCR。如果觉得文章不错的话,就给我点个赞吧,嘿嘿😋。Spring 官方还提供了各种文件的 reader,可以根据需求和场景选择合适的 reader,例如 tika 能实现 html、doc、ppt 和 pdf 多种文件的读取,但是对于 pdf 文件个人不太建议使用 tika 库,要想学习更多知识就请关注我吧❤️。

image-20250716225000509

个人项目

厚米匹配

网址:厚米匹配系统

前端仓库:https://github.com/dnwwdwd/homieMatching-fronted

后端仓库:https://github.com/dnwwdwd/homieMatching

灵犀 BI

网址:鱼智能 BI

前端仓库:https://github.com/dnwwdwd/Lingxi-BI-fronted

后端仓库:https://github.com/dnwwdwd/Lingxi-BI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/89377.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89377.shtml

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

相关文章

TypeScript 配置全解析:tsconfig.json、tsconfig.app.json 与 tsconfig.node.json 的深度指南

前言在现代前端和后端开发中&#xff0c;TypeScript 已经成为许多开发者的首选语言。然而&#xff0c;TypeScript 的配置文件&#xff08;特别是多个配置文件协同工作时&#xff09;常常让开发者感到困惑。本文将深入探讨 tsconfig.json、tsconfig.app.json 和 tsconfig.node.j…

读书笔记(学会说话)

1、一个人只有会说话&#xff0c;才会有好人缘&#xff0c;做事才会顺利。会说话的人容易成功。善于说话的人易成功&#xff0c;而不善说话的人往往寸步难行。我们要把话说得好听&#xff0c;同时更要把事做得漂亮。或许一句话&#xff0c;一件事&#xff0c;就可能使人生的旅途…

私有服务器AI智能体搭建-大模型选择优缺点、扩展性、可开发

以下是主流 AI 框架与模型的对比分析&#xff0c;涵盖其优缺点、扩展性、可开发性等方面。 文章目录一、AI 框架对比二、主流大模型对比三、扩展性对比总结四、可开发性对比总结五、选择建议&#xff08;按场景&#xff09;六、未来趋势一、AI 框架对比 框架优点缺点扩展性可开…

OpenCV直线段检测算法类cv::line_descriptor::LSDDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该类用于实现 LSD (Line Segment Detector) 直线段检测算法。LSD 是一种快速、准确的直线检测方法&#xff0c;能够在不依赖边缘检测的前提下直接从…

Go语言流程控制(if / for)

分支结构package mainimport ("fmt""strconv" )/* 1.顺序结构 2.分支结构 3.循环结构 *//* if 条件1 {// 条件1为真时执行的代码 } else if 条件2 {// 条件1为假但条件2为真时执行的代码 } else {// 所有条件均为假时执行的代码 }一种特殊的条件分支结构if…

wx小程序设置沉浸式导航文字高度问题

第一步&#xff1a;在app.json中设置"navigationStyle": "custom"第二步骤&#xff1a;文件的home.js中// pages/test/test.js Page({/*** 页面的初始数据*/data: {statusBarHeight: 0,navBarHeight: 44 // 自定义导航内容区高度(单位px)},/*** 生命周期函…

C++算法竞赛篇:DevC++ 如何进行debug调试

C算法竞赛篇&#xff1a;DevC 如何进行debug调试前言一、准备工作&#xff1a;编译生成可执行程序二、核心步骤&#xff1a;设置断点与启动调试1. 设置断点2. 启动调试模式三、调试操作&#xff1a;逐步执行与变量监控1. 逐步执行代码2. 监控变量值变化四、调试结束前言 在算法…

语音大模型速览(三)- cosyvoice2

CosyVoice 2: Scalable Streaming Speech Synthesis with Large Language Models 论文链接&#xff1a;https://arxiv.org/pdf/2412.10117代码链接&#xff1a;https://github.com/FunAudioLLM/CosyVoice 一句话总结 CosyVoice 2 是一款改进的流式语音合成模型&#xff0c;其…

-lstdc++与-static-libstdc++的用法和差异

CMakeLists.txt 里写了&#xff1a; target_link_libraries(${PROJECT_NAME} PRIVATEgccstdc ) target_link_options(${PROJECT_NAME} PRIVATE -static-libstdc)看起来像是“链接了两次 C 标准库”&#xff0c;其实它们的作用完全不同&#xff1a;1. target_link_libraries(...…

Redis学习其二(事务,SpringBoot整合,持久化RDB和AOF)

文章目录5,事务5.1Redis 事务不保证原子性的原因5.2事务操作过程5.3监控6,SpringBoot整合Redis6.1Redis客户端6.1.1Jedis简单使用6.1.2Lettuce&Jedis6.2配置相关6.3使用6.3.1使用RedisTemplate6.3.2Redis工具类7,持久化RDB7.1RDB持久化原理7.2触发机制save命令flushall命令…

springboot项目部署到K8S

java后台 创建harbor镜像拉取Secret&#xff1a;kubectl create secret docker-registry harbor-regcred \--docker-server \ #harbor仓库地址--docker-username \ #harbor 账号--docker-password \ #harbor密码-n productionDockerfile FROM *harbor地址*/library/custom-jdk…

【FPGA开发】一文轻松入门Modelsim的基本操作

Modelsim仿真的步骤 &#xff08;1&#xff09;创建新的工程。 &#xff08;2&#xff09;在弹出的窗口中&#xff0c;确定项目名和工作路径&#xff0c;库保持为work不变(如有需要可以根据需求进行更改)。 &#xff08;3&#xff09;添加已经存在的文件&#xff08;rtl代码和t…

服务攻防-Java组件安全FastJson高版本JNDI不出网C3P0编码绕WAF写入文件CI链

服务攻防-Java组件安全&FastJson&高版本JNDI&不出网C3P0&编码绕WAF&写入文件CI链26天 原创 朝阳 Sec朝阳 2025年07月18日 09:23 湖北 标题已修改 演示环境&#xff1a; https://github.com/lemono0/FastJsonParty FastJson全版本Docker漏洞环境(涵盖1.…

【Python】DRF核心组件详解:Mixin与Generic视图

在 Django REST Framework (DRF) 中&#xff0c;mixins.CreateModelMixin、mixins.ListModelMixin、GenericAPIView 和 GenericViewSet 是构建 API 视图的核心组件。以下是对这些组件的主要方法及其职责的简要说明&#xff0c;内容清晰且结构化&#xff1a;1. mixins.CreateMod…

HTML+CSS+JS基础

文章目录&#xff08;一&#xff09;html1.常见标签&#xff08;1&#xff09;注释&#xff08;2&#xff09;标题 h1~h6&#xff08;3&#xff09;段落 p&#xff08;4&#xff09;换行与空格 br \ &#xff08;5&#xff09;格式化标签 b i s u&#xff08;6&#xff09;…

Vue导出Html为Word中包含图片在Microsoft Word显示异常问题

问题背景 碰到一个问题&#xff1a;将包含图片和SVG数学公式的HTML内容导出为Word文档时&#xff0c;将图片都转为ase64格式导出&#xff0c;在WPS Word中显示正常&#xff0c;但是在Microsoft Word中出现图片示异常。具体问题表现 WPS兼容性&#xff1a;在WPS中显示正常&#…

椭圆曲线密码学 Elliptic Curve Cryptography

密码学是研究在存在对抗行为的情况下还能安全通信的技术。即算法加密信息&#xff0c;再算法解密出信息。加密分为两类 1. Symmetric-key Encryption (secret key encryption) 即一种密钥&#xff0c;加密和解密使用同一密钥&#xff0c;可相互转换 2. Asymmetric-key Encry…

wedo牛-----第47节(免费分享图纸)

夸克网盘&#xff1a;https://pan.quark.cn/s/4b40a8d18979 高清图纸源文件&#xff0c;需要的请自取

Unity | AmplifyShaderEditor插件基础(第十集:噪声的种类+火焰制作-下)

目录 一、&#x1f44b;&#x1f3fb;前言 二、圆火焰 三、制作梯度 梯度成品预览 1.GradientSample节点 2.gradient的用法 3.time节点 四、添加颜色 Color节点 五、火焰摇摆 1.X方向的移动 2.Y方向的移动 3.Z方向的移动 4.把xyz组合起来 Panner节点 六、摆放和…

黑马Node.js全套入门教程,nodejs新教程含es6模块化+npm+express+webpack+promise等_ts对象笔记

1.1 什么是运行环境&#xff1f; 运行环境是指代码正常运行所需的必要环境&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; V8引擎负责解析和执行JavaScript代码。内置API是由运行环境提供的特殊接口&#xff0c;只能在所属的运行环境中被调用 1.2 JavaScrip…