二.springBoot项目集成ElasticSearch及使用

二.springBoot项目集成ElasticSearch及使用

1.依赖引入

复制代码
<!--elasticsearch搜索引擎-->
<!--高版本7.0后TransportClient已被淘汰,用rest-high-level-client代替-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.6.2</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.6.2</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>7.6.2</version>
    <scope>compile</scope>
</dependency>

2.ElasticSearch常见用法

java 复制代码
package com.lmy.elasticSearchTest;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.lmy.elasticSearchTest.pojo.User;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
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.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

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

/**
 * es 7.6.x API测试
 */
public class ElasticSearchApiTest {

    private RestHighLevelClient restHighLevelClient;

    // 集群地址,多个用,隔开
    @Value("${es.hosts}")
    private String hosts = "127.0.0.1";
    // 使用的端口号
    @Value("${es.port}")
    private int port = 9200;
    @Value("${es.userName}")
    private String userName = "";
    @Value("${es.password}")
    private String password = "";

    // 使用的协议
    private static String schema = "http";

    // 连接超时时间
    private static int connectTimeOut = 1000;
    // 连接超时时间
    private static int socketTimeOut = 30000;
    // 获取连接的超时时间
    private static int connectionRequestTimeOut = 500;

    @Before
    public void init() throws IOException {
        /*// 单机模式
        restHighLevelClient = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));*/

        // 集群模式
        /*用户认证对象*/
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        /*设置账号密码*/
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));

        RestClientBuilder builder = RestClient.builder(this.getHostList().toArray(new HttpHost[0]))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    @Override
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
                        return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                    }
                });
        // 异步httpclient连接延时配置
        builder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
            @Override
            public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
                requestConfigBuilder.setConnectTimeout(connectTimeOut);
                requestConfigBuilder.setSocketTimeout(socketTimeOut);
                requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeOut);
                return requestConfigBuilder;
            }
        });
        restHighLevelClient = new RestHighLevelClient(builder);

    }

    public ArrayList<HttpHost> getHostList() {
        ArrayList<HttpHost> hostList = new ArrayList<>();
        String[] hostStrs = hosts.split(",");
        for (String host : hostStrs) {
            hostList.add(new HttpHost(host, port, schema));
        }
        return hostList;
    }

    /**
     * 索引操作
     * @throws IOException
     */

    // 测试索引的创建 Request
    @Test
    public void testCreateIndex() throws IOException {
        // 创建索引的请求
        CreateIndexRequest request = new CreateIndexRequest("api_test");
        //
        CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(response);
        restHighLevelClient.close();
    }

    // 测试索引是否存在
    @Test
    public void testIndexIsExists() throws IOException {
        GetIndexRequest request = new GetIndexRequest("api_test");
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
        restHighLevelClient.close();
    }

    // 测试索引删除
    @Test
    public void testDeleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("blog");
        AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
        //查看索引是否存在
        System.out.println(response.isAcknowledged());
        restHighLevelClient.close();
    }

    /**
     * 文档操作
     */

    // 测试添加文档
    @Test
    public void testAddDocument() throws IOException {
        // 创建一个User对象
        User user = new User("wangmazi", 99);
        // 创建请求
        IndexRequest request = new IndexRequest("api_test");
        // 制定规则 PUT /api_test/_doc/1
        request.id("3");//设置文档id
        request.timeout(TimeValue.timeValueMillis(1000));//设置超时时间
        request.source(JSON.toJSONString(user), XContentType.JSON);//设置添加的文档内容
        // 客户端发送请求,获取响应的结果
        IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        System.out.println(response);
        restHighLevelClient.close();
    }

    // 测试获得文档信息
    @Test
    public void testGetDocument() throws IOException {
        GetRequest request = new GetRequest("api_test","_all", "1");
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        // 打印文档内容
        System.out.println(response.getSourceAsString());
        System.out.println(request);
        restHighLevelClient.close();
    }

    // 获取文档,判断是否存在 get /api_test/_doc/1
    @Test
    public void testDocumentIsExists() throws IOException {
        GetRequest request = new GetRequest("api_test","_all", "1");
        // 不获取返回的 _source的上下文了
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("_none_");
        boolean exists = restHighLevelClient.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
        restHighLevelClient.close();
    }

    // 测试更新文档内容
    @Test
    public void testUpdateDocument() throws IOException {
        UpdateRequest request = new UpdateRequest("api_test","_all", "1");
        User user = new User("lmy", 25);
        request.doc(JSON.toJSONString(user), XContentType.JSON);
        UpdateResponse update = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        System.out.println(update.status());
        restHighLevelClient.close();
    }

    // 测试删除文档
    @Test
    public void testDeleteDocument() throws IOException {
        DeleteRequest request = new DeleteRequest("api_test","_all", "3");
        request.timeout("1s");
        DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        System.out.println(response.status());
        restHighLevelClient.close();
    }

    // 查询
    // SearchRequest 搜索请求
    // SearchSourceBuilder 条件构造
    // HighlightBuilder 高亮
    // TermQueryBuilder 精确查询
    // MatchAllQueryBuilder
    // xxxQueryBuilder ...
    /**
     * QueryBuilders:termQuery(精确查询),matchQuery(匹配查询),rangeQuery(范围查询),multiMatchQuery(多个字段上进行匹配查询),wildcardQuery(通配符查询,支持 * 和 ? 通配符),existsQuery(检查文档中是否存在某个字段),
     * BoolQueryBuilder:复合查询 must(AND)、should(OR)、must_not(NOT)、filter(过滤条件 必须满足 filter 子句中的所有条件)
     */
    @Test
    public void testSearch() throws IOException {
        List<User> userList = new ArrayList<>();
        // 1.创建查询请求对象 参数为索引名(库名)
        SearchRequest request = new SearchRequest("api_test");
        // 2.构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // (1)查询条件 使用QueryBuilders工具类创建
        // 精确查询
        TermQueryBuilder termQuery = QueryBuilders.termQuery("name", "lmy");
        // 匹配查询
        MatchAllQueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "lmy");
        // 范围查询
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
        rangeQueryBuilder.gte("17");
        rangeQueryBuilder.lte("20");
        // 复合查询 must、should、must_not、filter
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.matchQuery("name", "lmy"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("age").gte("17").lte("20"));
        // (2)其他<可有可无>:(可以参考 SearchSourceBuilder 的字段部分)
        // 设置高亮
        searchSourceBuilder.highlighter(new HighlightBuilder());
        // 分页
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(3);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        // (3)条件投入
        searchSourceBuilder.query(boolQueryBuilder);
        // 3.添加条件到请求
        request.source(searchSourceBuilder);
        // 4.客户端查询请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 5.查看返回结果
        SearchHits hits = response.getHits();
        System.out.println(JSON.toJSONString(hits));
        System.out.println("========================");
        for (SearchHit h:hits.getHits()) {
            System.out.println(h.getSourceAsMap());
            User user = BeanUtil.mapToBean(h.getSourceAsMap(), User.class,true);
            userList.add(user);
        }
        System.out.println(userList);
        restHighLevelClient.close();
    }

    // 特殊的,真的项目一般会 批量插入数据
    @Test
    public void testBulk() throws IOException {
        BulkRequest request = new BulkRequest();
        request.timeout("10s");

        ArrayList<User> list = new ArrayList<>();
        list.add(new User("lmy-1",18));
        list.add(new User("lmy-2",19));
        list.add(new User("lmy-3",20));
        list.add(new User("lmy-4",21));

        // 批量请求处理
        for (User u :list) {
            request.add(
              new IndexRequest("api_test").source(JSON.toJSONString(u),XContentType.JSON)
            );
        }
        BulkResponse bulk = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
        System.out.println(bulk.status());
        restHighLevelClient.close();
    }
}
相关推荐
G皮T10 分钟前
【Elasticsearch】检索高亮
大数据·elasticsearch·搜索引擎·全文检索·kibana·检索·高亮
一勺菠萝丶19 分钟前
Spring Boot + MyBatis/MyBatis Plus:XML中循环处理List参数的终极指南
xml·spring boot·mybatis
RainbowSea2 小时前
问题:后端由于字符内容过长,前端展示精度丢失修复
java·spring boot·后端
风象南2 小时前
SpringBoot 控制器的动态注册与卸载
java·spring boot·后端
我是一只代码狗2 小时前
springboot中使用线程池
java·spring boot·后端
hello早上好3 小时前
JDK 代理原理
java·spring boot·spring
PanZonghui3 小时前
Centos项目部署之运行SpringBoot打包后的jar文件
linux·spring boot
沉着的码农3 小时前
【设计模式】基于责任链模式的参数校验
java·spring boot·分布式
zyxzyx6663 小时前
Flyway 介绍以及与 Spring Boot 集成指南
spring boot·笔记
一头生产的驴5 小时前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf