zoukankan      html  css  js  c++  java
  • 【ElasticSearch(十三)进阶】SpringBoot整合ElasticSearch7.14.0 基本教程

    【ElasticSearch(十三)进阶】SpringBoot整合ElasticSearch7.14.0 基本教程

    一、接入方式

    1.端口9300:TCP

    1)spring-data-elasticsearch:transport-api.jar:

    springboot版本不同,transport-api.jar 不同,不能适配es版本

    7.x 已经不建议使用,8以后就要废弃


    2.端口9200:HTTP

    1)JestClient

    非官方,更新慢

    2)RestTemplate

    模拟发HTTP请求,ES很多操作需要自己封装,麻烦

    3)HttpClient

    同上

    4)Elasticsearch-Rest-Client(我们选择的)

    官方RestClient,封装了ES操作,API层次分明,上手简单


    (使用指南)

    https://www.elastic.co/guide/en/elasticsearch/client/index.html



    二、搭建项目

    我使用的版本是ElasticSearch 7.14,配合SpringBoot搭建项目。




    三、导入Maven

    由于父依赖spring-boot-dependencies导入的elasticsearch依赖版本是7.12.1的,所以这里我们另外在<properties>标签下定义下elasticsearch版本是7.14的。

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.14.0</elasticsearch.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    
        <!-- 导入es的rest-high-level-client和elasticsearch server-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.14.0</version>
        </dependency>
    
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    

    四、建立Config

    建立config文件夹,创建类ElasticSearchConfig ,作为我们的配置文件。

    给容器中注入一个RestHighLevelClient

    package com.musecho.gulimallsearch.config;
    
    import org.apache.http.HttpHost;
    import org.elasticsearch.client.*;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class ElasticSearchConfig {
    
        /**
         * 创建单例模式的RequestOptions,使得所有请求共用
         */
        public static final RequestOptions COMMON_OPTIONS;
        static {
            RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
    //        builder.addHeader("Authorization", "Bearer " + TOKEN);
    //        builder.setHttpAsyncResponseConsumerFactory(
    //                new HttpAsyncResponseConsumerFactory
    //                        .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
            COMMON_OPTIONS = builder.build();
        }
    
        @Bean
        public RestHighLevelClient client() {
            RestClientBuilder builder=RestClient.builder(new HttpHost("localhost", 9200, "http"));
            RestHighLevelClient client = new RestHighLevelClient(builder);
            return client;
        }
    }
    

    五、测试:保存数据

    保存一个user信息,使用index()

    package com.musecho.gulimallsearch;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.musecho.gulimallsearch.config.ElasticSearchConfig;
    import com.musecho.gulimallsearch.pojo.User;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.action.index.IndexResponse;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import java.io.IOException;
    
    @SpringBootTest
    public class GulimallSearchApplicationTests {
    
        @Autowired
        private RestHighLevelClient client;
    
        /**
         * jackson的objectMapper
         */
        ObjectMapper objectMapper=new ObjectMapper();
    
        /**
         * 测试RestHighLevelClient注入是否成功
         */
        @Test
        public void contextLoads() {
            System.out.println(client);
        }
    
        /**
         * 保存用户数据
         */
        @Test
        public void indexData() throws IOException {
            //指定索引和id
            IndexRequest request=new IndexRequest("users");
            request.id("1");
    
            //数据转为json格式
            User user=new User("zhengkeke","女",9);
            String userString=objectMapper.writeValueAsString(user);
            request.source(userString, XContentType.JSON);
    
            //执行保存操作
            IndexResponse indexResponse=client.index(request, ElasticSearchConfig.COMMON_OPTIONS);
    
            System.out.println(indexResponse);
        }
    
    }
    

    通过Kinaba查询是否添加成功:

    GET /users/_search

    返回结果如下, 保存数据成功

    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "users",
            "_type" : "_doc",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "name" : "zhengkeke",
              "sex" : "女",
              "age" : 9
            }
          }
        ]
      }
    }
    

    六、测试:复杂检索数据

    现在用java结合ES实现这个查询

    #搜索 address中包含mill的所有人的年龄分布以及平均年龄
    GET /bank/_search
    {
      "query":{
        "match":{
          "address":"mill"
        }
      },
      "aggs":{
        "ageAgg":{
          "terms":{
            "field": "age",
            "size": 10
          }
        },
        "ageAvg":{
          "avg":{
            "field":"age"
          }
        }
      }
    }
    

    类GulimallSearchApplicationTests中添加方法searchData()

    /**
         * 复杂检索数据
         */
    @Test
    public void searchData() throws IOException {
        //1.创建检索请求
        SearchRequest searchRequest = new SearchRequest();
        //指定索引
        searchRequest.indices("bank");
        //指定DSL,检索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    
        //1.1 构造检索条件
        //address中包含mill
        searchSourceBuilder.query(QueryBuilders.matchQuery("address", "mill"));
        //按照前10种年龄分布进行聚合
        TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
        searchSourceBuilder.aggregation(ageAgg);
        //求所有人年龄的平均值
        AvgAggregationBuilder ageAvg = AggregationBuilders.avg("ageAvg").field("age");
        searchSourceBuilder.aggregation(ageAvg);
    
        System.out.println(searchSourceBuilder);
        searchRequest.source(searchSourceBuilder);
    
    
        //2.执行检索
        SearchResponse searchResponse = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
    
        //3.分析结果
        //3.1 查看查询结果
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            System.out.println(hit);
        }
        //3.2 查看聚合结果
        Aggregations aggs = searchResponse.getAggregations();
    
        Terms ageAgg2 = aggs.get("ageAgg");
        for (Terms.Bucket bucket : ageAgg2.getBuckets()) {
            System.out.println("年龄:" + bucket.getKeyAsString()+"==> 人数:"+bucket.getDocCount());
        }
        System.out.println();
    
        Avg ageAvg2 = aggs.get("ageAvg");
        System.out.println("平均年龄:" + ageAvg2.getValue());
    }
    

    控制台打印结果:

    //请求条件
    {
        "query": {
            "match": {
                "address": {
                    "query": "mill", 
                    "operator": "OR", 
                    "prefix_length": 0, 
                    "max_expansions": 50, 
                    "fuzzy_transpositions": true, 
                    "lenient": false, 
                    "zero_terms_query": "NONE", 
                    "auto_generate_synonyms_phrase_query": true, 
                    "boost": 1
                }
            }
        }, 
        "aggregations": {
            "ageAgg": {
                "terms": {
                    "field": "age", 
                    "size": 10, 
                    "min_doc_count": 1, 
                    "shard_min_doc_count": 0, 
                    "show_term_doc_count_error": false, 
                    "order": [
                        {
                            "_count": "desc"
                        }, 
                        {
                            "_key": "asc"
                        }
                    ]
                }
            }, 
            "ageAvg": {
                "avg": {
                    "field": "age"
                }
            }
        }
    }
    
    //查询结果
    {
        "_index" : "bank",
        "_type" : "account",
        "_id" : "970",
        "_score" : 5.4032025,
        "_source" : {
            "account_number" : 970,
            "balance" : 19648,
            "firstname" : "Forbes",
            "lastname" : "Wallace",
            "age" : 28,
            "gender" : "M",
            "address" : "990 Mill Road",
            "employer" : "Pheast",
            "email" : "forbeswallace@pheast.com",
            "city" : "Lopezo",
            "state" : "AK"
        }
    }
    {
        "_index" : "bank",
        "_type" : "account",
        "_id" : "136",
        "_score" : 5.4032025,
        "_source" : {
            "account_number" : 136,
            "balance" : 45801,
            "firstname" : "Winnie",
            "lastname" : "Holland",
            "age" : 38,
            "gender" : "M",
            "address" : "198 Mill Lane",
            "employer" : "Neteria",
            "email" : "winnieholland@neteria.com",
            "city" : "Urie",
            "state" : "IL"
        }
    }
    {
        "_index" : "bank",
        "_type" : "account",
        "_id" : "345",
        "_score" : 5.4032025,
        "_source" : {
            "account_number" : 345,
            "balance" : 9812,
            "firstname" : "Parker",
            "lastname" : "Hines",
            "age" : 38,
            "gender" : "M",
            "address" : "715 Mill Avenue",
            "employer" : "Baluba",
            "email" : "parkerhines@baluba.com",
            "city" : "Blackgum",
            "state" : "KY"
        }
    }
    {
        "_index" : "bank",
        "_type" : "account",
        "_id" : "472",
        "_score" : 5.4032025,
        "_source" : {
            "account_number" : 472,
            "balance" : 25571,
            "firstname" : "Lee",
            "lastname" : "Long",
            "age" : 32,
            "gender" : "F",
            "address" : "288 Mill Street",
            "employer" : "Comverges",
            "email" : "leelong@comverges.com",
            "city" : "Movico",
            "state" : "MT"
        }
    }
    
    //聚合结果
    年龄:38==> 人数:2
    年龄:28==> 人数:1
    年龄:32==> 人数:1
    
    平均年龄:34.0
    
  • 相关阅读:
    第一册:lesson forty five。
    第一册:lesson forty three。
    马化腾2015港大演讲。
    Swing实现文件选择(目录选择)附导出
    SVN强制注释
    Websphere内存溢出的日志
    sql server2008 搭建链接服务器成功后查询时报Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI10" for linked server "XXXXX". 的解决方法
    UML图例
    jSP的3种方式实现radio ,checkBox,select的默认选择值。
    通过js子页面回写父页面,改变父页面控件的值
  • 原文地址:https://www.cnblogs.com/musecho/p/15180003.html
Copyright © 2011-2022 走看看