Java调用Elasticsearch API实现全文检索,搭配MinIO文件存储

这篇具有很好参考价值的文章主要介绍了Java调用Elasticsearch API实现全文检索,搭配MinIO文件存储。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

应用背景:
对存储在MinIO服务器的文件实现全文检索。也可以是其他服务器或本地文件,本文仅详细介绍MinIO文件的读取及转换。通过Elasticsearch的Ingest-Attachment插件抽取文件内容,支持Word、Excel、PDF、TXT等格式文件,无需手动解析文件内容。

上代码,详细解释可以阅读注释、

1.引入依赖

springboot已经管理好了依赖,只需引入spring-boot-starter-data-elasticsearch

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

Java调用Elasticsearch API实现全文检索,搭配MinIO文件存储

 

2.配置文件

elasticsearch:
  host: 192.168.2.154
  port: 9200

3.配置类

@Setter
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
public class ElasticSearchConfig {

    private String host;

    private Integer port;

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost(this.host, this.port)));
        return client;
    }
}

4.实现类

package com.dmp.document.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.dmp.common.constant.HttpStatus;
import com.dmp.common.core.page.PageDomain;
import com.dmp.common.core.page.TableDataInfo;
import com.dmp.common.core.page.TableSupport;
import com.dmp.document.domain.dto.DocElasticsearchDto;
import com.dmp.document.domain.entity.DocDocument;
import com.dmp.document.service.DocDocumentService;
import com.dmp.document.service.ElasticsearchService;
import com.dmp.document.service.MinioClientService;
import com.dmp.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.common.text.Text;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;

import static com.sun.webkit.network.URLs.newURL;
import static org.elasticsearch.client.RequestOptions.DEFAULT;

/**
 * @author daixin
 * @version 1.0
 * @description: TODO
 * @date 2022/11/23 17:38
 */
@Slf4j
@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {
    @Autowired
    private RestHighLevelClient esClient;

    @Autowired
    private MinioClientService minioClientService;

    @Autowired
    private DocDocumentService docDocumentService;

    @Autowired
    private ISysConfigService sysConfigService;


    public String createFileIndex(String id, String projectId) throws Exception {
        String result = null;
        InputStream is = null;
        try{
            Date date1 = new Date();
            //查询系统内存储的文件key
            DocDocument docDocument = docDocumentService.getById(id);
            String path = docDocument.getPath();
            //获取minio下载签名
            String url = minioClientService.getDownloadLink("file-bucket",path);
            //请求minio获取文件流
            URL url2= newURL(url);
            HttpURLConnection conn=(HttpURLConnection) url2.openConnection();
            conn.setDoInput(true);
            conn.connect();
            is = conn.getInputStream();
            //转码base64
            byte[] fileByteStream = IOUtils.toByteArray(is);
            String base64String = new String(Base64.getEncoder().encodeToString(fileByteStream).getBytes(), "UTF-8");
            //封装ES请求
            IndexRequest request;
            Map attachmentMap = new HashMap();
            attachmentMap.put("data", base64String);
            attachmentMap.put("fileName", docDocument.getName());
            attachmentMap.put("projectId",projectId);
            //查询系统参数
            String esIndex = sysConfigService.selectConfigByKey("es_index");
            String esPipe = sysConfigService.selectConfigByKey("es_pipe");
            //配置查询请求参数
            request = new IndexRequest(esIndex);
            request.id(String.valueOf(docDocument.getId()));
            request.setPipeline(esPipe);//文件抽取管道,需提前创建
            request.source(JSONObject.toJSONString(attachmentMap), XContentType.JSON);
            IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
            response.status().toString();
            Date date2 = new Date();
            log.info("创建索引-----耗时:{}ms" , (date2.getTime() - date1.getTime()));
        }catch(Exception e){
            throw e;
        }finally {
            is.close();
        }
        return result;
    }
    @Override
    public TableDataInfo matchContent(String content, String projectId) {
        //此处为若依框架提供的分页,可改为你自己的分页
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        //查询系统参数
        String esIndex = sysConfigService.selectConfigByKey("es_index");
        SearchRequest searchRequest = new SearchRequest(esIndex);
        //布尔查询,检索标题和内容,过滤项目id
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery(content, "attachment.content","fileName");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(matchQueryBuilder);
        if(projectId != null){
            boolQueryBuilder.filter(QueryBuilders.termQuery("projectId", projectId));
        }
        sourceBuilder.query(boolQueryBuilder);
        //配置高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("attachment.content"); //content字段高亮
        highlightBuilder.field("fileName");//fileName字段高亮
        highlightBuilder.preTags("<span style='color:red'>"); //高亮前缀
        highlightBuilder.postTags("</span>"); //高亮后缀
        sourceBuilder.highlighter(highlightBuilder);
        //分页查询
        sourceBuilder.from((pageNum-1)*pageSize).size(pageSize);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = null;
        try {
            searchResponse = esClient.search(searchRequest, DEFAULT);
        } catch (Throwable e) {
            //捕捉最高级别异常,确保打印详细信息
            e.printStackTrace();
        }
        if(searchResponse.getHits() == null){
            rspData.setTotal(0);
            rspData.setRows(null);
            return rspData;
        }
        List<DocElasticsearchDto> docElasticsearchList = new ArrayList<>();
        Long totalHits = searchResponse.getHits().getTotalHits().value;//匹配总条数,用于分页显示
        for (SearchHit hit : searchResponse.getHits()){
            //查询结果
            String source = hit.getSourceAsString();
            DocElasticsearchDto docElasticsearchDto = JSONObject.parseObject(source, DocElasticsearchDto.class);
            docElasticsearchDto.setId(hit.getId());
            //处理高亮字段
            Map<String, HighlightField> map = hit.getHighlightFields();
            if(map.containsKey("attachment.content")) {
                StringBuilder matchContent = new StringBuilder();
                for(Text t : map.get("attachment.content").fragments()){
                    matchContent.append(t.toString());
                }
                docElasticsearchDto.getAttachment().put("content",matchContent.toString());
            }
            if(map.containsKey("fileName")) {
                StringBuilder matchFileName =  new StringBuilder();
                for(Text t : map.get("fileName").fragments()){
                    matchFileName.append(t.toString());
                }
                docElasticsearchDto.setFileName(matchFileName.toString());
            }
            docElasticsearchList.add(docElasticsearchDto);
        }
        rspData.setTotal(totalHits);
        rspData.setRows(docElasticsearchList);
        return rspData;
    }
    @Override
    public void deleteFileIndex(String id) throws IOException {
        //查询系统参数,ES索引名称
        String esIndex = sysConfigService.selectConfigByKey("es_index");
        //删除索引
        DeleteRequest deleteRequest = new DeleteRequest(esIndex,id);
        esClient.delete(deleteRequest, RequestOptions.DEFAULT);
    }

}

示例的实现是先从数据库查询到保存的文件信息,然后从minio文件存储服务器获取文件流,由于minio提供以签名的方式获取流,这里就直接使用了,你也可以是其他服务器,或者直接获取文件对象。在创建索引的时候直接发送文件流,Ingest-Attachment插件会帮你实现转换。Ingest-Attachment的安装可参考Docker安装Elasticsearch及相关插件详细步骤,全程亲测避坑_冰糖码奇朵的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-512586.html

到了这里,关于Java调用Elasticsearch API实现全文检索,搭配MinIO文件存储的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 双方案-基于Mysql 与 ElasticSearch实现关键词提示搜索与全文检索

    就喜欢搞这种不需要怎么费劲的东西,只需要把思路阐述清楚,随笔性质的博文,顺手啊,几乎不用改定就可以当博文发布出去。 那么,这里的话我们要做的就是实现这个的一个搜索功能,这个前端我就不说了,实现起来起来其实还是容易的,就是费劲。我们主要关注

    2024年01月18日
    浏览(48)
  • springboot+Elasticsearch实现word,pdf,txt内容抽取并高亮分词全文检索

    文章目录 需求 一、环境 二、功能实现 1.搭建环境 2.文件内容识别 三.代码         产品希望我们这边能够实现用户上传PDF,WORD,TXT之内得文本内容,然后用户可以根据附件名称或文件内容模糊查询文件信息,并可以在线查看文件内容         项目开发环境:           

    2023年04月09日
    浏览(31)
  • ElasticSearch 实现 全文检索 支持(PDF、TXT、Word、HTML等文件)通过 ingest-attachment 插件实现 文档的检索

    Attachment 插件是 Elasticsearch 中的一种插件,允许将各种二进制文件(如PDF、Word文档等)以及它们的内容索引到 Elasticsearch 中。插件使用 Apache Tika 库来解析和提取二进制文件的内容。通过使用 Attachment 插件,可以轻松地在 Elasticsearch 中建立全文搜索功能,而无需事先转换二进制

    2024年02月05日
    浏览(38)
  • 全文检索-Elasticsearch-进阶检索

    本文记录谷粒商城高级篇的 Elasticsearch 进阶检索部分,续上之前记录的 Elasticsearch入门篇。 ES 支持两种基本方式检索 : 一个是通过使用 REST request URI 发送搜索参数(uri + 检索参数) 另一个是通过使用 REST request body 来发送它们(uri + 请求体) 请求体中写查询条件,语法: 示例

    2024年02月03日
    浏览(74)
  • Elasticsearch 全文检索 分词检索-Elasticsearch文章四

    https://www.elastic.co/guide/en/enterprise-search/current/start.html https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl-match-query.html Full text Query中,我们只需要把如下的那么多点分为3大类,你的体系能力会大大提升 很多api都可以查得到,我们只要大概知道有支持哪些功能 Elasticsearch 执行

    2024年02月14日
    浏览(39)
  • elasticsearch全文检索

    传送门 best_fields 传送门 most_fields 当查询多字段包含相同文本以不同方式分词的时候此参数最有用, 传送门 cross_fields phrase和phrase_prefix 传送门 传送门

    2024年02月07日
    浏览(34)
  • ElasticSearch-全文检索

    https://www.elastic.co/cn/what-is/elasticsearch 全文搜索属于最常见的需求,开源的Elasticsearch是目前全文搜索引擎的首选。 它可以快速地储存、搜索和分析海量数据。 维基百科、StackOverflow、Github都采用它。 Elastic的底层是开源库Lucene。但是,你没法直接用Lucene,必须自己写代码去调用

    2024年04月17日
    浏览(26)
  • ElasticSearch 实战:ElasticSearch文档全文检索

    Elasticsearch 实战:Elasticsearch 文档全文检索 全文检索是 Elasticsearch 的核心功能之一,它允许用户对文本内容进行高效的模糊搜索、词组匹配、同义词处理、停用词过滤等操作。以下是如何进行文档全文检索的详细步骤: **1. **全文匹配查询(Match Query) 最基础的全文检索查询是

    2024年04月11日
    浏览(35)
  • 使用Elasticsearch进行word,excel,PDF的全文检索 windows实现 超完整(ingest-attachment实现)

    首先要明确的一点就是Elasticsearch的版本要和ingest-attachment的版本一致,要不然没办法安装。然后还有一点JAVA版本要在11以上 先说说原理吧,其实就是将文件base64编码,然后再用插件读取文件内容并保存到es中。 安装完jdk之后用cmd查看一下java -version看看是否已经从1.8修改为了

    2024年02月13日
    浏览(28)
  • ES(Elasticsearch 全文检索)

    数据量大的时候 索引失效 =查询性能低 功能比较弱 对文档的内容进行分词,对词条创建索引,记录词条所在的文档信息根据词条查询到文档的id 从而查到文档 文档:每一条数据就是一条文档 词条:文档按照语义分成的词语 正向索引 根据文档的id创建索引 查询词条必须先找

    2024年02月05日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包