ElasticSearch7入门(五)SpringBoot2.3.0集成ElasticSearch7.5.2-HighLevelClient

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: ElasticSearch7入门(五)SpringBoot2.3.0集成ElasticSearch7.5.2-HighLevelClient

背景


今天来实现SpringBoot集成ElasticSearchElasticSearch官方提供了两种Java REST Client。推荐使用HighLevelClient的方式,HighLevelClient本身是基于Low Level REST Client封装而来。


The Java REST Client comes in 2 flavors:
Java Low Level REST Client: the official low-level client for Elasticsearch. It allows to communicate with an Elasticsearch cluster through http. Leaves requests marshalling and responses un-marshalling to users. It is compatible with all Elasticsearch versions.
Java High Level REST Client: the official high-level client for Elasticsearch. Based on the low-level client, it exposes API specific methods and takes care of requests marshalling and responses un-marshalling.


核心依赖


<!--ES-->
    <!--The High Level Java REST Client depends on the following artifacts and their transitive dependencies:
      org.elasticsearch.client:elasticsearch-rest-client
      org.elasticsearch:elasticsearch
    -->
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
      <version>7.5.2</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-client</artifactId>
      <version>7.5.2</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch</artifactId>
      <version>7.5.2</version>
    </dependency>


核心方法


package com.heartsuit.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
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.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * @Author Heartsuit
 * @Date 2020-06-04
 */
@Slf4j
@Component
public class ElasticSearchServiceImpl implements ElasticSearchService {
    private final RestHighLevelClient client;
    public ElasticSearchServiceImpl(RestHighLevelClient client) {
        this.client = client;
    }
    /**
     * 创建索引
     *
     * @param index 必须小写,格式参考文档,否则报错:Elasticsearch exception [type=invalid_index_name_exception, reason=Invalid index name [OK], must be lowercase]
     * @return 是否创建成功
     */
    @Override
    public boolean createIndex(String index) {
        CreateIndexResponse response;
        try {
            if (!this.existsIndex(index)) {
                response = client.indices().create(new CreateIndexRequest(index), RequestOptions.DEFAULT);
            } else {
                return true;//索引已存在
            }
        } catch (Exception e) {
            log.error("ElasticSearch 创建索引异常:{}", e.getMessage());
            return false;
        }
        return response.isAcknowledged();
    }
    /**
     * 判断索引是否存在
     *
     * @param index
     * @return
     */
    private boolean existsIndex(String index) throws IOException {
        return client.indices().exists(new GetIndexRequest(index), RequestOptions.DEFAULT);
    }
    /**
     * 删除索引
     *
     * @param index 必须小写,格式参考文档,否则:找不到大写索引名
     * @return 是否删除成功
     */
    @Override
    public boolean deleteIndex(String index) {
        AcknowledgedResponse response = null;
        try {
            if (this.existsIndex(index)) {
                response = client.indices().delete(new DeleteIndexRequest(index), RequestOptions.DEFAULT);
            } else {
                return true;//索引不存在
            }
        } catch (Exception e) {
            log.error("ElasticSearch 删除索引异常:{}", e.getMessage());
            return false;
        }
        return response.isAcknowledged();
    }
    /**
     * 创建文档
     * id相同则更新、不同则创建,数据格式(字段)不同则空,字段为追加模式
     *
     * @param index    索引
     * @param data     数据
     * @param dataType 格式类型    例:XContentType.JSON
     * @param id       唯一标识   put /index/1
     * @return
     */
    @Override
    public int insertDocument(String index, Object data, XContentType dataType, String id) {
        IndexRequest request = new IndexRequest(index);
        request.id(id);
        String dataString = JSONObject.toJSONString(data);
        request.source(dataString, dataType);
        IndexResponse response = null;
        try {
            response = client.index(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("ElasticSearch 创建文档异常:{}", e.getMessage());
        }
        return response != null ? response.status().getStatus() : 400;
    }
    /**
     * 获取文档
     *
     * @param index
     * @param id
     * @param mappingClass
     * @param <T>
     * @return
     */
    @Override
    public <T> T getDocument(String index, String id, Class<T> mappingClass) {
        GetResponse getResponse = null;
        try {
            if (this.existsIndex(index)) {
                GetRequest getRequest = new GetRequest(index, id);
                getResponse = client.get(getRequest, RequestOptions.DEFAULT);
                String sourceAsString = getResponse.getSourceAsString();
                if (sourceAsString == null || sourceAsString.isEmpty()) {
                    return null;
                }
                /**Jackson日期时间序列化问题:
                 * Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): no String-argument constructor/factory method to deserialize from String value ('2020-06-04 15:07:54')
                 */
//                ObjectMapper objectMapper = new ObjectMapper();
//                objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//                objectMapper.registerModule(new JavaTimeModule());
//                T result = objectMapper.readValue(sourceAsString, mappingClass);
                T result = JSON.parseObject(sourceAsString, mappingClass);
                return result;
            }
        } catch (Exception e) {
            log.error("ElasticSearch 获取文档异常:{}", e.getMessage());
        }
        return null;
    }
    /**
     * 更新文档信息
     *
     * @param index
     * @param data
     * @param dataType
     * @param id
     * @return
     */
    @Override
    public int updateDocument(String index, Object data, XContentType dataType, String id) {
        UpdateResponse updateResponse = null;
        try {
            if (this.existsIndex(index)) {
                UpdateRequest updateRequest = new UpdateRequest(index, id);
                String dataString = JSONObject.toJSONString(data);
                updateRequest.doc(dataString, dataType);
                updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
            }
        } catch (Exception e) {
            log.error("ElasticSearch 更新文档异常:{}", e.getMessage());
        }
        return updateResponse != null ? updateResponse.status().getStatus() : 400;
    }
    /**
     * 删除文档
     *
     * @param index
     * @param id
     * @return
     */
    @Override
    public int deleteDocument(String index, String id) {
        DeleteResponse deleteResponse = null;
        try {
            if (this.existsIndex(index)) {
                DeleteRequest deleteRequest = new DeleteRequest(index, id);
                deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
            }
        } catch (Exception e) {
            log.error("ElasticSearch 删除文档异常:{}", e.getMessage());
        }
        return deleteResponse != null ? deleteResponse.status().getStatus() : 400;
    }
    /**
     * 批量操作文档信息
     * 备注:暂局限入参list,可扩展其他<?>
     *
     * @param index
     * @param list     标识相同则覆盖,否则新增
     * @param dataType
     * @return
     */
    @Override
    public boolean batchInsertDocument(String index, List<?> list, XContentType dataType) {
        BulkRequest bulkRequest = new BulkRequest();
        for (Object obj : list) {
            // 自动生成id
            bulkRequest.add(new IndexRequest(index).source(JSON.toJSONString(obj), dataType));
        }
        BulkResponse bulk = null;
        try {
            bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("ElasticSearch批量操作文档信息异常:{}", e.getMessage());
        }
        return bulk != null && !bulk.hasFailures();
    }
    /**
     * 查询数据
     * 备注:可拓展深入精准查询、范围查询、模糊查询、匹配所有等
     *
     * @param index
     * @return
     */
    @Override
    public List<Map<String, Object>> searchDocument(String index) {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        MatchAllQueryBuilder termQueryBuilder = QueryBuilders.matchAllQuery();
        sourceBuilder.query(termQueryBuilder);
        // sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(sourceBuilder);
        SearchResponse search;
        try {
            search = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("ElasticSearch 查询数据异常:{}", e.getMessage());
            return null;
        }
        SearchHit[] hits = search.getHits().getHits();
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (SearchHit hit : hits) {
            mapList.add(hit.getSourceAsMap());
        }
        return mapList;
    }
    private void close(RestHighLevelClient client) {
        try {
            client.close();
        } catch (IOException e) {
            log.error("ElasticSearch 关闭异常:{}", e.getMessage());
        }
    }
}

Note: 使用FastJson替换了SpringBoot的默认Json解析器Jackson,


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
1月前
|
存储 搜索推荐 Java
|
2月前
|
Java
【极问系列】springBoot集成elasticsearch出现Unable to parse response body for Response
【极问系列】springBoot集成elasticsearch出现Unable to parse response body for Response
|
29天前
|
Java 测试技术 Maven
SpringBoot集成Elasticsearch
SpringBoot集成Elasticsearch
24 0
|
1月前
|
消息中间件 Java 关系型数据库
【二十】springboot整合ElasticSearch实战(万字篇)
【二十】springboot整合ElasticSearch实战(万字篇)
212 47
|
2月前
|
存储 关系型数据库 MySQL
ElasticSearch 入门
【2月更文挑战第7天】ElasticSearch 入门 简介 ElasticSearch 的基本概念 ElasticSearch 的查询流程 ElasticSearch 的更新流程
37 2
|
2月前
|
存储 自然语言处理 搜索推荐
ElasticSearch入门篇
ElasticSearch入门篇
|
2月前
|
Java Windows
【极光系列】springBoot集成elasticsearch
【极光系列】springBoot集成elasticsearch
|
11月前
|
NoSQL Java 测试技术
SpringBoot集成ElasticSearch在启动时报availableProcessors is already set to [8], rejecting [8]
SpringBoot集成ElasticSearch在启动时报availableProcessors is already set to [8], rejecting [8]
115 0
|
Java
ElasticSearch7入门(六)SpringBoot2.3.0集成ElasticSearch7.5.2-SpringData
ElasticSearch7入门(六)SpringBoot2.3.0集成ElasticSearch7.5.2-SpringData
293 0
|
缓存 自然语言处理 Java
springboot 2.0集成elasticsearch 7.6.2 (集群)关键字高亮显示(下)
springboot 2.0集成elasticsearch 7.6.2 (集群)关键字高亮显示(下)
181 0