spingboot2 整合ES7.2

时间:2022-07-22
本文章向大家介绍spingboot2 整合ES7.2,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

参考文档

包括中文分词:https://www.jianshu.com/p/d2afc19cafbd

拼音搜索:https://github.com/medcl/elasticsearch-analysis-pinyin/releases?after=v7.4.2

1.导入jar包:

<properties>
        <elasticsearch.version>7.2.0</elasticsearch.version>
    </properties>



<!-- Elasticsearch 一定要检查关联得依赖是否一致-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <exclusions>
                <!--自带es版本太低了需要排除-->
                <exclusion>
                    <groupId>org.elasticsearch</groupId>
                    <artifactId>elasticsearch</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.elasticsearch.client</groupId>
                    <artifactId>elasticsearch-rest-client</artifactId>
                </exclusion>
            </exclusions>
            <version>${elasticsearch.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>

2. ElasticSearchClientConfig高级客户端的配置

package com.unwulian.thirdserver.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author shiye
 * @create 2020-07-17 16:38
 */
@Configuration
public class ElasticSearchClientConfig {

    @Autowired
    private EsParamConfig esParamConfig;


    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost(esParamConfig.getHost(), esParamConfig.getPort(), esParamConfig.getScheme())));
        return client;
    }

}

3.编写配置文件

es:
  host: 127.0.0.1
  port: 9200
  scheme: http
  default_index: community_index
  timeout: 60

4. 配置文件的读取

package com.unwulian.thirdserver.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.io.Serializable;

/**
 * @author shiye
 * @create 2020-07-17 19:30
 */
@Configuration
@ConfigurationProperties(prefix = "es")
public class EsParamConfig implements Serializable {

    /**
     * 主机
     */
    private String host;

    /**
     * 端口
     */
    private int port;

    /**
     * http协议
     */
    private String scheme;

    /**
     * 索引库,默认为:community_index
     */
    private String default_index = "community_index";

    /**
     * 超时时间,到秒
     */
    private int timeout;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getScheme() {
        return scheme;
    }

    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    public String getDefault_index() {
        return default_index;
    }

    public void setDefault_index(String default_index) {
        this.default_index = default_index;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }
}

6.工具类编写,主要是配置索引,和分词

package com.unwulian.thirdserver.util;

import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;

import java.io.IOException;

/**
 * ES的配置文件
 *
 * @author shiye
 * @create 2020-07-20 11:46
 */
public class EsPropertyConfigUtil {

    /**
     * 索引设置
     * @param request
     * @return
     */
    public static CreateIndexRequest indexSetting(CreateIndexRequest request) {

        Settings.Builder builder = Settings.builder();
        builder.put("analysis.tokenizer.my_pinyin.type", "pinyin");

        /**********中文转拼音的配置**********/
        //keep_first_letter启用此选项时,例如:刘德华> ldh,默认值:true
        builder.put("analysis.tokenizer.my_pinyin.keep_first_letter", true);
        //limit_first_letter_length 设置first_letter结果的最大长度,默认值:16
        builder.put("analysis.tokenizer.my_pinyin.limit_first_letter_length", 16);
        //keep_full_pinyin当启用该选项,例如:刘德华> [ liu,de,hua],默认值:true
        builder.put("analysis.tokenizer.my_pinyin.keep_full_pinyin", true);
        //keep_joined_full_pinyin启用此选项时,例如:刘德华> [ liudehua],默认值:false
        builder.put("analysis.tokenizer.my_pinyin.keep_joined_full_pinyin", false);
        //keep_none_chinese 将非中文字母或数字保留在结果中,默认值:true
        builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese", true);
        //keep_none_chinese_together 保持非中国信一起,默认值:true,如:DJ音乐家- > DJ,yin,yue,jia,当设置为false,例如:DJ音乐家- > D,J,yin,yue,jia,注意:keep_none_chinese应先启用
        builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese_together", true);
        //keep_none_chinese_in_first_letter 将非中文字母保留在首字母中,例如:刘德华AT2016-> ldhat2016,默认值:true
        builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese_in_first_letter", false);
        //keep_none_chinese_in_joined_full_pinyin 将非中文字母保留在拼音中,例如:刘德华2016-> liudehua2016,默认值:false
        builder.put("analysis.tokenizer.my_pinyin.keep_none_chinese_in_joined_full_pinyin", true);
        //none_chinese_pinyin_tokenize 打破非中国信成单独的拼音项,如果他们是拼音,默认值:true,如:liudehuaalibaba13zhuanghan- > liu,de,hua,a,li,ba,ba,13,zhuang,han,注意: keep_none_chinese和keep_none_chinese_together应首先启用
        builder.put("analysis.tokenizer.my_pinyin.none_chinese_pinyin_tokenize", true);
        //keep_original 启用此选项后,还将保留原始输入,默认值:false
        builder.put("analysis.tokenizer.my_pinyin.keep_original", true);
        //lowercase 小写非中文字母,默认:true
        builder.put("analysis.tokenizer.my_pinyin.lowercase", true);
        //trim_whitespace 默认值:true
        builder.put("analysis.tokenizer.my_pinyin.trim_whitespace", true);
        //remove_duplicated_term 启用此选项后,将删除重复的术语以保存索引,例如:de的> de,默认值:false,注意:与位置相关的查询可能会受到影响
        builder.put("analysis.tokenizer.my_pinyin.remove_duplicated_term", true);
        //ignore_pinyin_offset 在6.0之后,严格限制偏移量,不允许使用重叠的标记,使用此参数时,忽略偏移量将允许使用重叠的标记,请注意,所有与位置相关的查询或突出显示都将变为错误,您应使用多个字段并为不同的字段指定不同的设置查询目的。如果需要偏移量,请将其设置为false。默认值:true。
        builder.put("analysis.tokenizer.my_pinyin.ignore_pinyin_offset", true);
        //keep_separate_first_letter启用该选项时,将保留第一个字母分开,例如:刘德华> l,d,h,默认:假的,注意:查询结果也许是太模糊,由于长期过频
        builder.put("analysis.tokenizer.my_pinyin.keep_separate_first_letter", true);

        /******************当前索引的分词器配置*******************/
        builder.put("analysis.analyzer.pinyin_analyzer.tokenizer", "my_pinyin");

        request.settings(builder);
        return request;
    }

    /**
     * 社区服务ES mapping 的 设置
     *
     * @param request
     * @return
     */
    public static CreateIndexRequest indexMappingCommunity(CreateIndexRequest request) throws IOException {
        XContentBuilder builder = null;
        builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.startObject("properties");
            {
                builder.startObject("coId");
                {
                    builder.field("type", "text");
                }
                builder.endObject();
                builder.startObject("coName");
                {
                    builder.field("type", "text");
                    builder.field("analyzer", "pinyin_analyzer");
                }
                builder.endObject();
                builder.startObject("cityId");
                {
                    builder.field("type", "text");
                }
                builder.endObject();
                builder.startObject("cityName");
                {
                    builder.field("type", "text");
                    builder.field("analyzer", "pinyin_analyzer");
                }
                builder.endObject();
                builder.startObject("areaId");
                {
                    builder.field("type", "text");
                }
                builder.endObject();
                builder.startObject("areaName");
                {
                    builder.field("type", "text");
                    builder.field("analyzer", "pinyin_analyzer");
                }
                builder.endObject();
            }
            builder.endObject();
        }
        builder.endObject();
        request.mapping(builder);
        return request;
    }
}

7. 测试代码

package com.unwulian.thirdserver;

import com.alibaba.fastjson.JSON;
import com.unwulian.common.thirdentity.CommunityEntity;
import org.apache.http.HttpHost;
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.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author shiye
 * @create 2020-07-17 17:01
 */
public class EsApplicationTest {

    //构建对象
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));
        return client;
    }


    //创建索引
    @Test
    public void testCreateIndex() throws IOException {
        RestHighLevelClient client = restHighLevelClient();

        try {
            //1.创建索引请求
            CreateIndexRequest request = new CreateIndexRequest("shiye_index");

            //2. 客户端执行请求
            CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);

            System.out.println(response);
        } finally {
            client.close();
        }
    }

    //测试索引是否存在
    @Test
    public void testExitIndex() throws IOException {
        RestHighLevelClient client = restHighLevelClient();
        try {
            //1.创建索引请求
            GetIndexRequest request = new GetIndexRequest("shiye_index");

            //2. 客户端执行请求
            boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);

            System.out.println("是否存在:" + exists);
        } finally {
            client.close();
        }
    }

    //删除索引
    @Test
    public void testDeleteIndex() throws IOException {
        RestHighLevelClient client = restHighLevelClient();
        try {
            //1.创建索引请求
            DeleteIndexRequest request = new DeleteIndexRequest("shiye_index");

            //2. 客户端执行请求
            AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);

            System.out.println("是否删除成功:" + response.isAcknowledged());
        } finally {
            client.close();
        }
    }

    //测试添加文档
    @Test
    public void testAddDoc() throws IOException {
        CommunityEntity communityEntity = new CommunityEntity();
        communityEntity.setCoId("EQ001");
        communityEntity.setCoName("宇宙天下");
        communityEntity.setAreaId("A001");
        communityEntity.setAreaName("蜀山区");
        communityEntity.setCityId("A002");
        communityEntity.setCityName("合肥市");

        RestHighLevelClient client = restHighLevelClient();

        try {
            //1.创建索引请求
            IndexRequest request = new IndexRequest("shiye_index");
            // 规则 : put /shiye_index/_doc/1
            request.id(communityEntity.getCoId());
            request.timeout(TimeValue.timeValueSeconds(1));
            request.timeout("1s");

            //2. 客户端执行请求
            request.source(JSON.toJSONString(communityEntity), XContentType.JSON);
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);

            System.out.println("对象是否创建成功:" + response.status());
        } finally {
            client.close();
        }
    }

    //获取上面创建的索引
    @Test
    public void getDocIndex() throws IOException {
        RestHighLevelClient client = restHighLevelClient();
        try {
            //1.创建索引请求
            GetRequest request = new GetRequest("shiye_index", "EQ001");
            // 规则 : get /shiye_index/_doc/1

            //2. 客户端执行请求
            GetResponse response = client.get(request, RequestOptions.DEFAULT);
            System.out.println("获取到的对象为:" + response.getSource());
        } finally {
            client.close();
        }
    }

    //跟新文档记录
    @Test
    public void testupdateDocIndex() throws IOException {
        CommunityEntity communityEntity = new CommunityEntity();
        communityEntity.setCoId("EQ001");
        communityEntity.setCoName("宇宙天下9999");
        communityEntity.setAreaId("A001999");
        communityEntity.setAreaName("蜀山区9999");
        communityEntity.setCityId("A002999");
        communityEntity.setCityName("合肥市9999");

        RestHighLevelClient client = restHighLevelClient();

        try {
            //1.创建索引请求
            UpdateRequest updateRequest = new UpdateRequest("shiye_index", "EQ001");
            // 规则 : put /shiye_index/_doc/1
            updateRequest.id(communityEntity.getCoId());
            updateRequest.timeout(TimeValue.timeValueSeconds(1));
            updateRequest.timeout("1s");

            updateRequest.doc(JSON.toJSONString(communityEntity), XContentType.JSON);

            //2. 客户端执行请求
            UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);

            System.out.println("对象是否跟新成功:" + response.status());
        } finally {
            client.close();
        }
    }

    //删除文档记录
    @Test
    public void testDeleteDoc() throws IOException {
        RestHighLevelClient client = restHighLevelClient();

        try {
            DeleteRequest request = new DeleteRequest("shiye_index", "EQ001");
            request.timeout("1s");

            DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);

            System.out.println("是否删除成功" + response.status());
        } finally {
            client.close();
        }
    }

    //批量导入数据
    @Test
    public void testBulkRequest() throws IOException {
        RestHighLevelClient client = restHighLevelClient();
        try {
            BulkRequest bulkRequest = new BulkRequest();
            bulkRequest.timeout("1s");

            List<CommunityEntity> list = new ArrayList<>();
            list.add(new CommunityEntity("EQ001", "宇宙天下1", "A002", "合肥市", "A001", "蜀山区1"));
            list.add(new CommunityEntity("EQ002", "宇宙天下2", "A002", "合肥市", "A001", "蜀山区1"));
            list.add(new CommunityEntity("EQ003", "宇宙天下3", "A002", "合肥市", "A001", "蜀山区1"));
            list.add(new CommunityEntity("EQ004", "宇宙天下4", "A002", "合肥市", "A001", "蜀山区1"));
            list.add(new CommunityEntity("EQ005", "宇宙天下5", "A002", "合肥市", "A001", "蜀山区1"));
            list.add(new CommunityEntity("EQ006", "宇宙天下6", "A002", "合肥市", "A001", "蜀山区1"));

            //准备批量请求数据
            for (CommunityEntity communityEntity : list) {
                bulkRequest.add(
                        new IndexRequest("shiye_index")
                                .id(communityEntity.getCoId())
                                .source(JSON.toJSONString(communityEntity), XContentType.JSON)
                );
            }

            BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
            System.out.println("批量创建是否成功:" + response.status());

        } finally {
            client.close();
        }
    }

    //查询
    @Test
    public void testSearchDoc() throws IOException {
        RestHighLevelClient client = restHighLevelClient();
        try {
            SearchRequest request = new SearchRequest("shiye_index");

            //构建搜索条件
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

            //QueryBuilders.termQuery 全匹配查询
            MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("eqName", "宇宙");

            sourceBuilder.query(queryBuilder);
            sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

            request.source(sourceBuilder);


            SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
            System.out.println("命中的数据为:" + searchResponse.getHits());
            System.out.println("===============================");

            for (SearchHit documentFields : searchResponse.getHits().getHits()) {
                System.out.println(documentFields.getSourceAsMap());
            }


        } finally {
            client.close();
        }

    }

}