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

Java实现读取转码写入ES构建检索PDF等文档全栈流程

背景

之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo,并已实现WebHook的搭建和触发流程接口。
传送门:
基于GitBucket的Hook构建ES检索PDF等文档全栈方案

使用ES检索PDF、word等文档快速开始

实现读取本地文件入库ES

总体思路:基于前面已经搭建的WebHook触发流程,接收到push更新消息之后,使用本地的git工具拉取最新变动。这些文件与我们的ES应用在同一台机器上,然后Java可以读取这些文件转码并交给ES处理。

我们先处理核心部分,也就是使用Java读取各种文档,如PDF、Word、txt等格式的文件解析并在ES中创建索引。

文件属性类

根据自己的需要,文件属性应至少包括文件名、文件类型、作者等字段,由于目标是可以通过浏览器页面直接打开文件,则需要包含文件的网络url(注意不是本地url地址)。

import lombok.Data;  
@Data  
public class FileSource {  private String title;  private String summary;  private String fileType;  private String fileUrl;  private String content;  private String author;  private String fileVersion;  private String createDate;  
}

使用Data注解可以自动生成Get、Set方法,不用自己复制粘贴了。

写入流程的实现

  • 使用tika库自动获取文件类型
public static String getFileTypeByDefaultTika(String filePathUrl) throws IOException, URISyntaxException {  // 从 URL 创建一个 File 对象  File file = new File(new URL("file:///" + filePathUrl).toURI());  // 使用 Tika 来检测文件的 MIME 类型  Tika tika = new Tika();  MediaType mediaType = MediaType.parse(tika.detect(file));  // 从 MIME 类型中提取文件的基本类型(如 pdf、image、video 等)  String fileType = mediaType.getSubtype();  return fileType;  
}
  • 根据文件类型判断排除音视频类文件
String fileType = getFileTypeByDefaultTika(pathUrl);  if (!fileType.contains("video")  && !fileType.contains("image")  && !"application/zip".equals(fileType)) {……}
  • 解析文件内容为Base64
public static String FileToBase64(String filePath) throws IOException {  byte[] fileContent = Files.readAllBytes(Paths.get(filePath));  return Base64.getEncoder().encodeToString(fileContent);  
}
  • 调用ES客户端进行写入,包括管道预处理文档
source.setFileType(fileType);  
String base64 = FileToBase64(pathUrl);  
source.setContent(base64);  String body = JSON.toJSONString(source);  
IndexRequest indexRequest = new IndexRequest().index("docwrite")  .source(body, XContentType.JSON)  .setPipeline("attachment") //上传时使用attachment pipline进行提取文件  .timeout(TimeValue.timeValueMinutes(10));  client.index(indexRequest, RequestOptions.DEFAULT);

这段代码是关于Elasticsearch的操作,具体是将一个文件转换为Base64格式,然后将其内容索引到Elasticsearch的指定索引中。

以下是对这段代码的详细解释:

  1. source.setFileType(fileType);
    • 这行代码为source对象设置一个文件的MIME类型或扩展名。
  2. String base64 = FileToBase64(pathUrl);
    • 调用FileToBase64函数,它接受一个文件路径,然后返回该文件的Base64编码内容。
    • pathUrl是一个文件的本地路径或URL。
    • 结果的Base64编码字符串存储在base64变量中。
  3. source.setContent(base64);
    • 将上述得到的Base64编码字符串设置为source对象的内容。
  4. String body = JSON.toJSONString(source);
    • 使用Fastjson将source对象转换为JSON格式的字符串。
    • 这个JSON字符串存储在body变量中。
  5. IndexRequest indexRequest = new IndexRequest().index("docwrite")
    • 创建一个新的IndexRequest对象,这是Elasticsearch Java客户端用于索引文档的请求对象。
    • 指定索引的名称为"docwrite"。
  6. .source(body, XContentType.JSON)
    • 设置请求体的内容为上面创建的body JSON字符串。
    • XContentType.JSON表示请求体的内容类型是JSON。
  7. setPipeline("attachment")
  • 为此索引请求设置一个pipeline,名为"attachment"。在Elasticsearch中,pipeline通常用于在索引文档之前对其进行某种处理或转换。在这里,它可能是为了处理或提取附件的内容。
  1. .timeout(TimeValue.timeValueMinutes(10));
  • 为此索引请求设置一个10分钟的超时时间。如果在这10分钟内请求未完成,它可能会超时。
  1. client.index(indexRequest, RequestOptions.DEFAULT);
  • 使用Elasticsearch客户端的index方法发送上面创建的indexRequest

调试过程出现SpringBoot启动报错实例化es客户端相关的错误:
Error creating bean with name 'elasticsearchRestHighLevelClient' defined in class

解决办法是添加如下的maven依赖吗,并将es客户端版本提高到7.15:

<!-- Spring Boot Elasticsearch Starter -->  
<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-data-elasticsearch</artifactId>  
</dependency>

测试索引流程运行

curl -XPOST -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8080/gitbucket/webhook

服务端打印收到的消息,没有报错,证明流程正常:

返回:我收到推送消息啦!

在Kibana查询ES中是否存在包含“License”的文件内容:

GET /docwrite/_search
{"query": {"match": {"attachment.content": {"query": "License","analyzer": "ik_smart"}}}
}

结果可以正确返回:

至此,后端ES索引流程基本完成了。

后续思考

后续需要实现的是从webhook消息中识别有效信息,使用git工作流获取更新,对新增文件进行上述索引流程。需要优化的是索引文件的属性尚不完整,文件的版本如何区分,以免重复录入文件,文件删除时是否从ES索引中删除等等这些流程。

http://www.lryc.cn/news/312348.html

相关文章:

  • 主流开发环境和开发语言介绍
  • C++ 使用 nlohmann::json存储json文件
  • 何为OOM(Out of Memory)?
  • SpringBoot+Mybatis-plus+shardingsphere实现分库分表
  • FPGA DDR3简介及时序
  • java网络编程 02 socket
  • 【Web安全】SQL各类注入与绕过
  • C++ 设计模式
  • 安卓使用ExoPlayer出现膨胀类异常
  • C++之析构函数
  • 108. 将有序数组转换为二叉搜索树【简单】
  • vue3中watch和watchEffect的区别!!!
  • 【JavaEE初阶 -- 计算机核心工作机制】
  • springcloud:3.6测试信号量隔离
  • AI化未来:智能科技的新纪元
  • Unity 整体界面淡入淡出效果
  • 反序列化逃逸 [安洵杯 2019]easy_serialize_php1
  • JavaScript中的包装类型详解
  • 如何向各大媒体网站投稿 海外媒体发稿平台有哪些
  • 基于SpringBoot的论坛系统(附项目源码+论文)
  • 堆以及堆的实现
  • 使用RabbitMQ实现延时消息自动取消的简单案例
  • Docker部署(ruoyi案例接上篇Docker之部署前后端分离项目)实施必会!!!!
  • 电脑中已经有多个模组压缩文件,如何通过小火星露谷管理器批量安装
  • [Linux]如何理解kernel、shell、bash
  • C++:Vector的使用
  • Redis之事务(详细解析)
  • Java项目:39 springboot007大学生租房平台的设计与实现
  • 安卓内存信息查看
  • Positional Encoding 位置编码