• springboot使用RestHighLevelClient7简单操作ElasticSearch7增删查改/索引创建


    本次操作是在  Windows上安装ElasticSearch7  进行操作

    导入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.es.demo</groupId>
        <artifactId>elastic-search-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>elastic-search-demo</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <elasticsearch.version>7.3.2</elasticsearch.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- Java High Level REST Client -->
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <version>${elasticsearch.version}</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>${elasticsearch.version}</version>
            </dependency>
            <!-- commons-lang3 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.4</version>
            </dependency>
            <!-- fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.54</version>
            </dependency>
            <!-- Swagger2 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.7.0</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.7.0</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

    application.yml

    server:
      port: 8833
    spring:
      application:
        name: elastic_search
    #es http方式
    elasticsearch:
      address: localhost:9200
    #  username: admin
    #  password: admin

    es配置加载

    package com.es.demo.config;
    
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    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.impl.client.BasicCredentialsProvider;
    import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestClientBuilder;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.Arrays;
    import java.util.Objects;
    
    /**
     * es RestHighLevelClient 配置
     * es 7.x之后 只支持http
     * @author qjc
     * @date 2019-07-19 10:33
     */
    @Configuration
    @Slf4j
    public class ESConfig {
        private static final int ADDRESS_LENGTH = 2;
        private static final String HTTP_SCHEME = "http";
        //权限验证
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    
        /**
         * 使用冒号隔开ip和端口
         */
        @Value("${elasticsearch.address}")
        private String[] address;
    
    //    @Value("${elasticsearch.username}")
    //    private String username;
    
    //    @Value("${elasticsearch.password}")
    //    private String password;
    
    
        @Bean
        public RestClientBuilder restClientBuilder() {
            HttpHost[] hosts = Arrays.stream(address)
                    .map(this::makeHttpHost)
                    .filter(Objects::nonNull)
                    .toArray(HttpHost[]::new);
            log.debug("hosts:{}", Arrays.toString(hosts));
            //配置权限验证
    //        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
            RestClientBuilder restClientBuilder = RestClient.builder(hosts).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                @Override
                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                    return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                }
            });
            return restClientBuilder;
        }
    
    
        @Bean(name = "highLevelClient")
        public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {
    //        restClientBuilder.setMaxRetryTimeoutMillis(60000);
            return new RestHighLevelClient(restClientBuilder);
        }
    
        /**
         * 处理请求地址
         * @param s
         * @return HttpHost
         */
        private HttpHost makeHttpHost(String s) {
            assert StringUtils.isNotEmpty(s);
            String[] address = s.split(":");
            if (address.length == ADDRESS_LENGTH) {
                String ip = address[0];
                int port = Integer.parseInt(address[1]);
                return new HttpHost(ip, port, HTTP_SCHEME);
            } else {
                return null;
            }
        }
    }

    swagger

    package com.es.demo.swagger;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.context.request.async.DeferredResult;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    @Configuration // 启动时就要加载
    @EnableSwagger2
    public class SwaggerConfig {
        private String version;
    
        @Bean
        public Docket createRestApi() {
    
            return new Docket(DocumentationType.SWAGGER_2)
                    .genericModelSubstitutes(DeferredResult.class)
                    .select()
                    .paths(PathSelectors.any())
                    .build().apiInfo(apiInfo());//.globalOperationParameters(pars);
    
        }
    
        private ApiInfo apiInfo() {
    
            return new ApiInfoBuilder().title("Earth server")
                    .description("****")
                    .termsOfServiceUrl("http://www.baidu.com")
                    .version("1.0").build();
        }
    }

    插入的实体:

    package com.es.demo.vo;
    
    
    import lombok.Data;
    
    /**
     * @Description:
     * @Param:
     * @Return:
     * @Author: qjc
     * @Date: 2019/10/18
     */
    @Data   //IDEA需要安装lombok:https://www.cnblogs.com/java-spring/p/9797560.html
    public class User {
    
        private String name;
    
        private int age;
    
        private Double money;
    
        private String address;
    
        private String birthday;
    }

    响应实体

    package com.es.demo.vo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    
    @Data
    @AllArgsConstructor
    public class ResponseBean {
        //状态码
        private Integer code;
        //返回信息
        private String message;
        //返回的数据
        private Object data;
    
    }

    es操作

    创建索引时需要用到IK分词器,请参考: Windows上安装ElasticSearch7的IK分词器

    package com.es.demo.controller;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.es.demo.utils.ESUtil;
    import com.es.demo.vo.ResponseBean;
    import com.es.demo.vo.User;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.elasticsearch.action.DocWriteResponse;
    import org.elasticsearch.action.delete.DeleteRequest;
    import org.elasticsearch.action.delete.DeleteResponse;
    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.replication.ReplicationResponse;
    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.CreateIndexRequest;
    import org.elasticsearch.client.indices.CreateIndexResponse;
    import org.elasticsearch.common.unit.TimeValue;
    import org.elasticsearch.common.xcontent.XContentBuilder;
    import org.elasticsearch.common.xcontent.XContentFactory;
    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.aggregations.Aggregation;
    import org.elasticsearch.search.aggregations.AggregationBuilders;
    import org.elasticsearch.search.aggregations.Aggregations;
    import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
    import org.elasticsearch.search.aggregations.bucket.terms.Terms;
    import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.sort.FieldSortBuilder;
    import org.elasticsearch.search.sort.SortBuilders;
    import org.elasticsearch.search.sort.SortMode;
    import org.springframework.web.bind.annotation.*;
    
    import javax.annotation.Resource;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @Author: qjc
     * @Date: 2019/09/18
     */
    @Api(value = "ES测试接口", tags = {"ES测试接口"})
    @RestController
    @RequestMapping("/es")
    @CrossOrigin(origins = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.DELETE, RequestMethod.PUT})
    @Slf4j
    public class ESTestController {
    
        @Resource
        private RestHighLevelClient restHighLevelClient;
        @Resource
        ESUtil esUtil;
    
        @ApiOperation(value = "es测试创建索引接口", notes = "es测试创建索引接口")
        @RequestMapping(value = "/create/index", method = RequestMethod.POST)
        public ResponseBean createIndex(@RequestParam String indexName) {
            try {
                XContentBuilder builder = XContentFactory.jsonBuilder()
                        .startObject()
                        .field("properties")
                        .startObject()
                        .field("name").startObject().field("index", "true").field("type", "keyword").endObject()
                        .field("age").startObject().field("index", "true").field("type", "integer").endObject()
                        .field("money").startObject().field("index", "true").field("type", "double").endObject()
                        .field("address").startObject().field("index", "true").field("type", "text").field("analyzer", "ik_max_word").endObject()
                        .field("birthday").startObject().field("index", "true").field("type", "date").field("format", "strict_date_optional_time||epoch_millis").endObject()
                        .endObject()
                        .endObject();
                CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
                createIndexRequest.mapping(builder);
                CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
                boolean acknowledged = createIndexResponse.isAcknowledged();
                if (acknowledged) {
                    return new ResponseBean(200, "创建成功", null);
                } else {
                    return new ResponseBean(1002, "创建失败", null);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @ApiOperation(value = "es测试是否存在索引接口", notes = "es测试是否存在索引接口")
        @RequestMapping(value = "/index/exists", method = RequestMethod.POST)
        public ResponseBean indexExists(@RequestParam String indexName) {
            boolean isExists = esUtil.isIndexExists(indexName);
            return new ResponseBean(200, "查询成功", isExists);
        }
    
        @ApiOperation(value = "es测试删除索引接口", notes = "es测试删除索引接口")
        @RequestMapping(value = "/delete/index", method = RequestMethod.POST)
        public ResponseBean deleteIndex(@RequestParam String indexName) {
            boolean isDelete = esUtil.deleteIndex(indexName);
            if (isDelete) {
                return new ResponseBean(200, "删除成功", null);
            } else {
                return new ResponseBean(10002, "删除失败", null);
            }
        }
    
        @ApiOperation(value = "es测试插入接口", notes = "es测试插入接口")
        @RequestMapping(value = "/insert/data", method = RequestMethod.POST)
        public ResponseBean findIndustryClassList(@RequestBody User user, @RequestParam String indexName) {
            IndexRequest indexRequest = new IndexRequest(indexName);
            String userJson = JSONObject.toJSONString(user);
            indexRequest.source(userJson, XContentType.JSON);
            try {
                IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
                if (indexResponse != null) {
                    String id = indexResponse.getId();
                    String index = indexResponse.getIndex();
                    long version = indexResponse.getVersion();
                    log.info("index:{},id:{}", index, id);
                    if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
                        System.out.println("新增文档成功!" + index + "-" + id + "-" + version);
                        return new ResponseBean(200, "插入成功", id);
                    } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
                        System.out.println("修改文档成功!");
                        return new ResponseBean(10001, "插入失败", null);
                    }
                    // 分片处理信息
                    ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
                    if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
                        System.out.println("分片处理信息.....");
                    }
                    // 如果有分片副本失败,可以获得失败原因信息
                    if (shardInfo.getFailed() > 0) {
                        for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
                            String reason = failure.reason();
                            System.out.println("副本失败原因:" + reason);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
        @ApiOperation(value = "es测试普通查询接口", notes = "es测试普通查询接口")
        @RequestMapping(value = "/query/data", method = RequestMethod.GET)
        public ResponseBean testESFind() {
            SearchRequest searchRequest = new SearchRequest("test_es");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            //如果用name直接查询,其实是匹配name分词过后的索引查到的记录(倒排索引);如果用name.keyword查询则是不分词的查询,正常查询到的记录
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("birthday").from("1991-01-01").to("2010-10-10").format("yyyy-MM-dd");//范围查询
    //        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name.keyword", name);//精准查询
            PrefixQueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery("name.keyword", "张");//前缀查询
    //        WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("name.keyword", "*三");//通配符查询
    //        FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("name", "三");//模糊查询
            FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort("age");//按照年龄排序
            fieldSortBuilder.sortMode(SortMode.MIN);//从小到大排序
    
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.must(rangeQueryBuilder).should(prefixQueryBuilder);//and or  查询
    
            sourceBuilder.query(boolQueryBuilder).sort(fieldSortBuilder);//多条件查询
            sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
            searchRequest.source(sourceBuilder);
            try {
                SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                SearchHits hits = response.getHits();
                JSONArray jsonArray = new JSONArray();
                for (SearchHit hit : hits) {
                    String sourceAsString = hit.getSourceAsString();
                    JSONObject jsonObject = JSON.parseObject(sourceAsString);
                    jsonArray.add(jsonObject);
                }
                return new ResponseBean(200, "查询成功", jsonArray);
            } catch (IOException e) {
                e.printStackTrace();
                return new ResponseBean(10001, "查询失败", null);
            }
        }
    
        @ApiOperation(value = "es测试聚合查询接口", notes = "es测试聚合查询接口")
        @RequestMapping(value = "/query/agg", method = RequestMethod.GET)
        public ResponseBean testESFindAgg() {
            SearchRequest searchRequest = new SearchRequest("test_es");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    
            TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("by_age").field("age");
            sourceBuilder.aggregation(termsAggregationBuilder);
    
            sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
            searchRequest.source(sourceBuilder);
    
            try {
                SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                Aggregations aggregations = searchResponse.getAggregations();
                Map<String, Aggregation> stringAggregationMap = aggregations.asMap();
                ParsedLongTerms parsedLongTerms = (ParsedLongTerms) stringAggregationMap.get("by_age");
                List<? extends Terms.Bucket> buckets = parsedLongTerms.getBuckets();
                Map<Integer, Long> map = new HashMap<>();
                for (Terms.Bucket bucket : buckets) {
                    long docCount = bucket.getDocCount();//个数
                    Number keyAsNumber = bucket.getKeyAsNumber();//年龄
                    System.err.println(keyAsNumber + "岁的有" + docCount + "个");
                    map.put(keyAsNumber.intValue(), docCount);
                }
                return new ResponseBean(200, "查询成功", map);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @ApiOperation(value = "es测试更新接口", notes = "es测试更新接口")
        @RequestMapping(value = "/update/data", method = RequestMethod.GET)
        public ResponseBean testESUpdate(@RequestParam String id, @RequestParam Double money) {
            UpdateRequest updateRequest = new UpdateRequest("test_es", id);
            Map<String, Object> map = new HashMap<>();
            map.put("money", money);
            updateRequest.doc(map);
            try {
                UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
                if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
                    return new ResponseBean(200, "更新成功", null);
                } else {
                    return new ResponseBean(10002, "删除失败", null);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return new ResponseBean(1003, "删除异常", null);
            }
        }
    
        @ApiOperation(value = "es测试删除接口", notes = "es测试删除接口")
        @RequestMapping(value = "/delete/data", method = RequestMethod.GET)
        public ResponseBean testESDelete(@RequestParam String id, @RequestParam String indexName) {
            DeleteRequest deleteRequest = new DeleteRequest(indexName);
            deleteRequest.id(id);
            try {
                DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
                if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
                    return new ResponseBean(1001, "删除失败", null);
                } else {
                    return new ResponseBean(200, "删除成功", null);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return new ResponseBean(1003, "删除异常", null);
            }
        }
    }
    package com.es.demo.utils;
    
    import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
    import org.elasticsearch.action.support.IndicesOptions;
    import org.elasticsearch.action.support.master.AcknowledgedResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.client.indices.GetIndexRequest;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    import java.io.IOException;
    
    /**
     * @Description:
     * @Author: qjc
     * @Date: 2019/10/30
     */
    @Component
    public class ESUtil {
    
        @Resource
        RestHighLevelClient restHighLevelClient;
    
        /**
         * 判断索引是否存在
         *
         * @param indexName
         * @return
         */
        public boolean isIndexExists(String indexName) {
            boolean exists = false;
            try {
                GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
                getIndexRequest.humanReadable(true);
                exists = restHighLevelClient.indices().exists(getIndexRequest,RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return exists;
        }
    
        /**
         * 删除索引
         *
         * @param indexName
         * @return
         */
        public boolean deleteIndex(String indexName) {
            boolean acknowledged = false;
            try {
                DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
                deleteIndexRequest.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN);
                AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
                acknowledged = delete.isAcknowledged();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return acknowledged;
        }
    
    }

     创建索引成功后,可以用以下方式查看

    通过访问swagger  http://localhost:8833/swagger-ui.html#/  可以进行如下操作

     源码地址:

    https://gitee.com/xiaorenwu_dashije/es_search_demo.git
  • 相关阅读:
    31天重构学习笔记21. 合并继承
    31天重构学习笔记15. 移除重复内容
    31天重构学习笔记22. 分解方法
    31天重构学习笔记18. 使用条件判断代替异常
    31天重构学习笔记19. 提取工厂类
    31天重构学习笔记24. 分解复杂判断
    31天重构学习笔记17. 提取父类
    大型项目的发布部署:第一章:发布部署流程
    HDU 2036 改革春风吹满地 数学题
    HDU 2051 Bitset
  • 原文地址:https://www.cnblogs.com/java-spring/p/11721615.html
Copyright © 2020-2023  润新知