spring boot 2.7整合Elasticsearch Java client + ingest attachment实现文档解析

news2024/11/24 1:36:04

一、软件环境

软件版本号备注
Spring boot2.7.23.x版本建议使用ElasticSearch8.x
ElasticSearch7.17.4ElasticSearch 7.x 可使用JDK 8
ElasticSearch 8.x 要求使用JDK 11+

二、安装ElasticSearch

下载地址:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.4-linux-x86_64.tar.gz

上传压缩包至/usr/local/

cd /usr/local/
//解压
tar -xvf elasticsearch-7.17.4-linux-x86_64.tar.gz

修改配置文件/usr/local/elasticsearch-7.17.4/config/elasticsearch.yml

注意 :后面需要跟一个空格

//数据存储路径,文件不存在则先创建
path.data: /usr/local/elasticsearch-7.17.4/data
//日志存储路径
path.logs: /usr/local/elasticsearch-7.17.4/logs
//在底部增加以下内容,以便支持设置密码
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

修改内存参数配置/usr/local/elasticsearch-7.17.4/config/jvm.options,可根据实际需求配置。

-Xms512m
-Xmx512m

JDK版本兼容,该版本默认要求JDK11,系统配置了JDK8,启动时会冲突,故进行以下调整

编辑/usr/local/elasticsearch-7.17.4/bin/elasticsearch-env,注释红框部分

ElasticSearch不能以root启动,为指定用户配置权限

//ElasticSearch不能以root启动,为指定用户配置权限
chown -R 用户名:用户名 /usr/local/elasticsearch-7.17.4
//启动ElasticSearch,需切换为非root用户
/usr/local/elasticsearch-7.17.4/bin/elasticsearch -d
//配置密码,需先启动一次ElasticSearch
/usr/local/elasticsearch-7.17.4/bin/elasticsearch-setup-passwords interactive

三、安装Kibana

下载地址:https://artifacts.elastic.co/downloads/kibana/kibana-7.17.4-linux-x86_64.tar.gz

上传压缩包至/usr/local/

cd /usr/local/
//解压
tar -zxvf kibana-7.17.4-linux-x86_64.tar.gz

编辑配置文件/usr/local/kibana-7.17.4-linux-x86_64/config/kibana.yml

//端口号
server.port: 5601

//服务器绑定地址,允许所有网络接口访问
server.host: "0.0.0.0"

//elasticsearch账户配置
elasticsearch.username: "kibana_system"
elasticsearch.password: "密码"

//中文
i18n.locale: "zh-CN"

kibana和ElasticSearch一样,不能以root启动,为指定用户配置权限

//kibana不能以root启动,为指定用户配置权限
chown -R 用户名:用户名 /usr/local/kibana-7.17.4-linux-x86_64

//前台启动
/usr/local/kibana-7.17.4-linux-x86_64/bin/kibana
//后台启动
nohup /usr/local/kibana-7.17.4-linux-x86_64/bin/kibana &

四、IK中文分词器

下载地址(根据对应的ElasticSearch版本号进行下载):

https://github.com/infinilabs/analysis-ik/releases

在ElasticSearch安装路径的plugins文件夹里,创建ik文件夹,如/usr/local/elasticsearch-7.17.4/plugins/ik,解压文件放到该路径下。

重启ElasticSearch即可。

五、Spring boot整合ElasticSearch

在Es7.15版本之后,es官方将它的高级客户端RestHighLevelClient标记为弃用状态。同时推出了全新的java API客户端Elasticsearch Java API Client,该客户端也将在Elasticsearch8.0及以后版本中成为官方推荐使用的客户端。

本文直接使用Elasticsearch Java API Client,后续方便升级8.x

pom.xml中增加:

<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>7.17.24</version>
</dependency>

配置文件:

spring.elasticsearch.uris=http://localhost:9200
spring.elasticsearch.username=elastic
spring.elasticsearch.password=*******

配置类ElasticsearchConfig:

@Configuration
public class ElasticsearchConfig {

    @Value("${spring.elasticsearch.uris}")
    private String uris;

    @Value("${spring.elasticsearch.username}")
    private String username;

    @Value("${spring.elasticsearch.password}")
    private String password;

    @Bean
    public ElasticsearchClient elasticsearchClient() {

        BasicCredentialsProvider credsProv = new BasicCredentialsProvider();
        credsProv.setCredentials(
            AuthScope.ANY, new UsernamePasswordCredentials(username, password)
        );
        RestClient restClient = RestClient.builder(
                HttpHost.create(uris)).setHttpClientConfigCallback(hc -> hc.setDefaultCredentialsProvider(credsProv)).build();

        #多节点可参考
        /*
        RestClient restClient = RestClient.builder(
            new HttpHost("192.168.1.10", 9200),
            new HttpHost("192.168.1.11", 9200),
            new HttpHost("192.168.1.12", 9200)).build();
        */
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());

        return new ElasticsearchClient(transport);
    }
}

在service类中自动装配ElasticsearchClient,后续直接使用

@Autowired
private ElasticsearchClient esClient;

六、索引相关操作

1.索引是否存在

http请求

GET /索引名称

JAVA  API

BooleanResponse existsResponse = esClient.indices()
                .exists(builder -> builder.index("索引名称"));
if (existsResponse.value()) {
    //存在
}else{
    //不存在
}

2.创建索引

http请求

PUT /索引名称
{
  //指定默认分词器为ik_max_word
  "settings" : {
      "index" : {
          "analysis.analyzer.default.type": "ik_max_word"
      }
  },
  "mappings": {
    "properties": {
      "字段1": {
        "type": "keyword"    //keyword不进行分词
      },
      "字段2": {
        "type": "text"       //text进行分词
      },
      "字段3": {
        "type":   "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      }
    }
  }
}

JAVA  API

//方式一
//定义映射
TypeMapping typeMapping = new TypeMapping.Builder()
                .properties("integer字段", p -> p.integer(i -> i))
                .properties("keyword字段",p->p.keyword(k -> k))
                .properties("text字段", p -> p.text(t -> t))
                .properties("日期字段", p -> p.date(d -> d.format("yyyy-MM-dd")))
                .properties("日期时间字段", p -> p.date(d -> d.format("yyyy-MM-dd HH:mm:ss")))
                .build();
esClient.indices().create(new CreateIndexRequest.Builder()
                .index("索引名称")
                .mappings(typeMapping)
                .build());

//方式二、根据json内容创建索引
String mappings = """
                {
                  "mappings" : {
                    "properties" : {
                      "integer字段" : {
                        "type" : "integer"
                      },
                      "keyword字段" : {
                        "type" : "keyword"
                      },
                      "text字段" : {
                        "type" : "text"
                      },
                      "日期字段" : {
                        "type" : "date",
                        "index" : false,
                        "format" : "yyyy-MM-dd"
                      },
                      "日期时间字段" : {
                        "type" : "date",
                        "index" : false,
                        "format" : "yyyy-MM-dd HH:mm:ss"
                      }
                    }
                  }
                }
                """;
esClient.indices().create(new CreateIndexRequest.Builder()
                .index("索引名称")
                .withJson(new StringReader(mappings))
                .build());

3.查询索引映射信息

http请求

GET /索引名称/_mapping

JAVA  API

GetMappingResponse response = esClient.indices()
            .getMapping(builder -> builder.index("索引名称"));
IndexMappingRecord indexMappingRecord = response.get("索引名称");
TypeMapping typeMapping = indexMappingRecord.mappings();
Map<String, Property> properties=typeMapping.properties();
List<IndexMapping> mappings=new ArrayList<>();
for(String key:properties.keySet()){
    IndexMapping mapping_item=new IndexMapping();
    //字段名称
    mapping_item.setField_name(key);
    String json_str=String.valueOf(properties.get(key)._get());
    json_str=json_str.substring(json_str.indexOf("Property: ")+9);
    JSONObject property_json= JSONObject.parseObject(json_str);
    //字段类型
    mapping_item.setField_type(property_json.getString("type"));
    //自定义格式
    if(property_json.containsKey("format")){
        mapping_item.setField_format(property_json.getString("format"));
    }
    mappings.add(mapping_item);
}

4.向索引添加映射字段

http请求

PUT /索引名称/_mapping
{
  "properties": {
    "新增字段": {
      "type": "keyword"
    }
  }
}

JAVA  API

//JSONObject mappings 为要增加的映射内容,参考http请求,这里省略细节
PutMappingResponse response=esClient.indices()
        .putMapping(new PutMappingRequest.Builder()
        .index("索引名称")
        .withJson(new StringReader(mappings.toString()))
        .build());
// 响应状态
Boolean acknowledged = response.acknowledged();

5.删除索引

http请求

DELETE /索引名称

JAVA  API

DeleteIndexResponse response = esClient.indices()
                .delete(builder -> builder.index("索引名称");
// 响应状态
Boolean acknowledged = response.acknowledged();

七、文档相关操作

1.添加文档

http请求

POST /索引名称/_doc/文档id
{
  "字段1": "内容",
  "字段2": "内容"
}

JAVA  API

// 插入文档到索引
//JSONObject json为文档内容
IndexRequest<Object> request = new IndexRequest.Builder<>()
            .index("索引名称")
            .id(”文档id“)
            .document(json)
            .build();
IndexResponse response = esClient.index(request);

2.编辑文档

http请求

PUT /索引名称/_doc/文档id
{
  "要修改的字段1":"要修改的内容",
  "要修改的字段2":"要修改的内容"
}

JAVA  API

//要修改的内容用Map组装
Map<String,Object> updateMap=new HashMap<>();
UpdateRequest<Object, Object> updateRequest = new UpdateRequest.Builder<>()
                .index("索引名称")
                .id(”文档id“)
                .doc(updateMap)
                .build();
 UpdateResponse<Object> updateResponse = esClient.update(updateRequest, Object.class);

3.根据id查询文档

http请求

GET /索引名称/_doc/文档id

JAVA  API

GetRequest getRequest = new GetRequest.Builder()
                .index("索引名称")
                .id(”文档id“)
                .build();
GetResponse<Object> response = esClient.get(getRequest, Object.class);
if (response.found()) {
    return response.source();
} else {
    throw new MyException(ResultEnum.DATA_IS_EXIST.getCode(),"数据不存在");
}

4.删除文档

http请求

DELETE /索引名称/_doc/文档id

JAVA  API

//支持批量删除,String[] id_arr为要删除的文档id数组
List<BulkOperation> bulkOperations = new ArrayList<>();
for(int i=0;i<id_arr.length;i++){
    String del_id=id_arr[i];
    bulkOperations.add(new BulkOperation.Builder().delete(
        d -> d.id(del_id).index("索引名称")).build());
}
BulkResponse bulkResponse = esClient.bulk(e -> e.index("索引名称").operations(bulkOperations));

5.筛选文档

http请求

GET blog/_search
{
  "query": {
    "bool" : {
      //必须满足的条件
      "must" : [
        //精确匹配
        {"term" : { "字段名称" : "自动内容" }},
        //模糊查询
        {"query_string": {
          "default_field": "字段名称",
          "query": "*模糊匹配内容*"
        }}
      ],
      //排除的条件
      "must_not" : [
        //精确匹配
        {"term" : { "字段名称" : "自动内容" }},
        //模糊查询
        {"query_string": {
          "default_field": "字段名称",
          "query": "*模糊匹配内容*"
        }}
      ]
    }
  },
  //排序规则
  "sort": [
    {
      //根据评分排序
      "_score": {
        "order": "desc"
      }
    },
    {
      "字段名称": {
        "order": "desc"
      }
    }
  ],
  //从第几条开始获取,从0开始
  "from":  0,
  //获取多少条
  "size":  10
}

JAVA  API

//queryJson是查询条件的json,参考http方式
SearchRequest searchRequest = new SearchRequest.Builder()
                .index("索引名称")
                .withJson(new StringReader(queryJson.toString()))
                .build();
SearchResponse<Object> response = esClient.search(searchRequest,Object.class);
List<Hit<Object>> hits = response.hits().hits();
//不需要输出文档id的话可以不要
List<Map<String,Object>> data_list = hits.stream().map(p->{
            Map<String,Object> map=new HashMap<>();
            map.put("docoment_id",p.id());
            map.putAll((Map<String, Object>)p.source());
            return map;
    }).collect(Collectors.toList());
//data_list是数据list,
//符合条件的数据总数为(int)response.hits().total().value()

八、结合ingest attachment实现文档解析

1.安装ingest attachment插件

下载地址(版本号可根据对应的ElasticSearch版本号进行替换):

https://artifacts.elastic.co/downloads/elasticsearch-plugins/ingest-attachment/ingest-attachment-7.17.4.zip

安装方法:

切换至ElasticSearch根目录,执行

#linux
./bin/elasticsearch-plugin install file:///path/to/ingest-attachment-7.17.4.zip
#windows
./bin/elasticsearch-plugin install file:///C:/path/to/ingest-attachment-7.17.4.zip

重启ElasticSearch,定义文本抽取管道

PUT /_ingest/pipeline/attachment
{
    "description": "Extract attachment information",
    "processors": [
        {
            "attachment": {
                "field": "content",
                "ignore_missing": true
            }
        },
        {
            "remove": {
                "field": "content"
            }
        }
    ]
}

attachment中指定要过滤的字段为content,所以写入Elasticsearch时需要将文档内容放在content字段,传入内容需为文档的base64编码。支持txt、word、Excel、PPT、PDF等文件格式。

2.文件转base64编码

// 文件路径
String filePath = "E:/xxx/xxx.pdf"; // 请替换为你的文件路径
// 读取文件字节
byte[] fileBytes = Files.readAllBytes(Paths.get(filePath)); // 读取文件内容
String base64_str = Base64.getEncoder().encodeToString(fileBytes); // 编码为Base64字符串

3.实现文档解析

/**
 * 模拟管道处理,仅模拟,不会真正插入文档
 */
Map<String, Object> source = new HashMap<>();
source.put("content", "文档的base64编码");
SimulateResponse response = client.ingest().simulate(builder -> builder
            .id("my-pipeline")
            .docs(documentBuilder -> documentBuilder
                    .index("索引名称")
                    .id(”文档id“)
                    .source(JsonData.of(source))));
log.info("response={}", response);

4.在文档索引的过程中使用

Map<String, Object> source = new HashMap<>();
source.put("content", "文档的base64编码");
IndexRequest<Object> request = new IndexRequest.Builder<>()
            .index("索引名称")
            .id(”文档id“)
            .document(JsonData.of(source))
            .pipeline("attachment")
            .build();
        IndexResponse response = esClient.index(request);
        logger.info(response.toString());

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

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

相关文章

网站建设中,虚拟主机的各项指标和参数

虚拟主机的各项指标和参数主要包括空间大小、并发连接数、带宽限制、流量限制、CPU限制、内存以及IO速度等。以下是对这些指标和参数的详细介绍&#xff1a; 空间大小&#xff1a;空间大小通常以MB或GB为单位&#xff0c;表示虚拟主机可以容纳的数据量。例如&#xff0c;一个1…

地级市-城市创业活跃度(每百人新创企业数)(2000-2021年)

城市创业活跃度通常指一个城市在一定时期内新创企业的数量和质量&#xff0c;它反映了城市的创业环境、创业者的积极性和创造力。根据中的研究&#xff0c;创业活跃度&#xff08;Entre_Activation&#xff09;作为反映区域层面创业活动积极程度的核心指标&#xff0c;被广泛用…

【Vue】Vue扫盲(二)指令:v-for 、v-if、v-else-if、v-else、v-show

【Vue】Vue扫盲&#xff08;一&#xff09;事件标签、事件修饰符&#xff1a;click.prevent click.stop click.stop.prevent、按键修饰符、及常用指令 文章目录 一、v-for遍历数组数组角标遍历对象&#xff1a;Key作用介绍 二、v-if、v-show基本用法&#xff1a;案例&#xff1…

【unity框架开发12】从零手搓unity存档存储数据持久化系统,实现对存档的创建,获取,保存,加载,删除,缓存,加密,支持多存档

文章目录 前言一、Unity对Json数据的操作方法一、JsonUtility方法二、Newtonsoft 二、持久化的数据路径三、数据加密/解密加密方法解密方法 四、条件编译指令限制仅在编辑器模式下进行加密/解密四、数据持久化管理器1、存档工具类2、一个存档数据3、存档系统数据类4、数据存档存…

【Photoshop——肤色变白——曲线】

1. 三通道曲线原理 在使用RGB曲线调整肤色时&#xff0c;你可以通过调整红、绿、蓝三个通道的曲线来实现黄皮肤到白皮肤的转变。 黄皮肤通常含有较多的红色和黄色。通过减少这些颜色的量&#xff0c;可以使肤色看起来更白。 具体步骤如下&#xff1a; 打开图像并创建曲线调…

几何完备的3D分子生成/优化扩散模型 GCDM-SBDD - 评测

GCDM 是一个新的 3D 分子生成扩散模型&#xff0c;与之前的 EDM 相比&#xff0c;GCDM 优化了其中的图神神经网络部分&#xff0c;使用手性敏感的 SE3 等变神经网络 GCPNET 代替了 EDM 中的 EGNN&#xff0c;让节点间消息传递、聚合根据手性不同而进行。本文对 GCDM-SBDD&#…

DMN决策引擎入门知识点

本文主要讲解Camunda是如何使用Dmn决策引擎&#xff0c;体验地址:www.jeecgflow.com Dmn决策表定义 Dmn在线设计 命中策略(Hit Policy) 策略名称策略描述Unique只有一个或者没有规则可以满足。决策表的结果包含满足规则的输出条目。如果超过一个规则满足&#xff0c;那么就违…

电脑知识:适用于 Windows 10 的 PDF 编辑器列表

PDF 是一种流行的、多功能且安全的文件格式&#xff0c;用于在线共享文档。但是&#xff0c;如果没有合适的应用程序&#xff0c;查看和编辑 PDF 文件可能会变得复杂。 幸运的是&#xff0c;有很多 PDF 编辑器可以帮助您更正重要文档上的错误、填写表格、为合同添加签名、更改…

【个人成长】编程小白如何成为大神?

1. 选择适合自己的编程语言 作为新手&#xff0c;选择一门适合自己的编程语言至关重要。不同的编程语言有不同的应用领域和特点。以下是几种适合初学者的编程语言&#xff1a; Python&#xff1a;广泛应用于数据科学、人工智能、自动化脚本和Web开发等领域。它语法简洁易懂&a…

Faker:自动化测试数据生成利器

Faker&#xff1a;自动化测试数据生成利器 前言1. 安装2. 多语言支持3. 常用方法3.1 生成姓名和地址3.2 生成电子邮件和电话号码3.3 生成日期和时间3.4 生成公司名称和职位3.5 生成文本和段落3.6 生成图片和颜色3.7 生成用户代理和浏览器信息3.8 生成文件和目录3.9 生成UUID和哈…

GPIO的原理

GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 可配置为8种输入输出模式 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 输入…

【Iceberg分析】Iceberg 1.6.1 源码使用IDEA本地编译

Iceberg 1.6.1 源码使用IDEA本地编译 文章目录 Iceberg 1.6.1 源码使用IDEA本地编译下载文件配置调整gradle相关修改bulid.gradlegradle.properties在IDEA上构建编译打包 可能出现的问题彩蛋与Spark部署Spark与Iceberg集成部署 下载 网络条件允许的情况下&#xff0c;使用git直…

引领智慧文旅新纪元,开启未来旅游新境界

融合创新科技&#xff0c;重塑旅游体验&#xff0c;智慧文旅项目定义旅游新未来 在全球化的浪潮中&#xff0c;旅游已成为连接世界的重要纽带。天津信之鸥科技有限公司&#xff08;以下简称“信鸥科技”&#xff09;今日宣布&#xff0c;公司倾力打造的智慧文旅项目正式投入运营…

10.继承与Data Member

目录 1、只要继承不要多态 2、加上多态 3、多重继承 4、虚拟继承 在C继承模型中&#xff0c;一个derived class object所表现出来的东西&#xff0c;是其自己的members加上其base class(es) members的总和。至于derived class members和base class(es) members的排列顺序&a…

基坑气膜:为清洁施工提供强力保障—轻空间

随着城市建设的不断推进&#xff0c;环保要求也日益提高。基坑气膜作为一种新型的施工技术&#xff0c;不仅在防尘降噪方面表现出色&#xff0c;还能支持复杂的施工设备运行&#xff0c;真正实现了从源头解决扬尘和噪音问题。 高效防尘&#xff0c;优化施工环境 传统施工中&…

Hyper-V管理器连接到服务器出错。请检查虚拟机管理服务是否正在运行以及是否授权你连接到此服务器。

尝试连接到服务器”XXXXXX"时出错。请检查虚拟机管理服务是否正在运行以及是否授权你连接到此服务器。 计算机"XXXXXX"上的操作失败: WinRM客户端无法处理该请求。如果身份验证方案与Kerberos不同&#xff0c;或者客户端计算机未加入到域中&#xff0c;则必须使…

工业物联网一直是风口,可视化大屏就是门面

工业物联网作为当下的热门领域&#xff0c;一直处于风口浪尖。而在这个领域中&#xff0c;可视化大屏确实充当着重要的门面角色。 可视化大屏以其震撼的视觉效果和直观的数据展示&#xff0c;为工业物联网赋予了强大的表现力。当人们走进工业物联网的应用场景&#xff0c;首先映…