Springboot 整合Elasticsearch

1 java操作ES方式

1.1 操作ES 9300端口(TCP) 但开发中不在9300进行操作
ES集群节点通信使用的也是9300端口

如果通过9300操作ES,需要与ES建立长连接  可通过引入spring-data-elasticsearch:transport-api.jar

不在9300操作原因:
	1.springboot版本不同,transport-api.jar不同,不能适配ES版本
	2.官方在7.x版本已经不建议在9300操作ES,8以后会废弃ES通过9300操作的jar包
1.2 操作ES 9200端口(HTTP) 优选Elasticsearch-Rest-Client
通过9200对ES发送Http请求就可以了
1.使用第三方JestClient操作ES:更新慢
2.RestTemplate、HttpClient、OkHttp:发送HTTP请求,但如果操作ES一些DSL语句,需要自己封装,麻烦
3.Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client):官方RestClient,封装了ES操作,API层次分明,上手简单

2 整合

2.1引入elasticsearch-rest-high-level-client依赖
xml 复制代码
<!--elasticsearch-->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.4.2</version>
</dependency>
刷新Maven 会发现elasticsearch和elasticsearch-rest-client版本是7.17.4,并不是7.4.2



原因是因为springboot对ES版本做了管理,当前springboot默认整合spring-data-elasticsearch操作ES
修改版本问题
如果使用Maven进行一个直接或间接继承spring-boot-dependencies(比如spring-boot-starter-parent)的构建,并想覆盖一个特定的
第三方依赖版本,可以添加<properties>标签,并重写第三方依赖版本
xml 复制代码
<properties>
    <elasticsearch.version>7.4.2</elasticsearch.version>
</properties>
如果使用<scope>import</scope>,将spring-boot-dependencies添加到自己的dependencyManagement片段,
那么必须重新定义artifact而不是重写第三方依赖版本
xml 复制代码
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>2.7.3</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
		<dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>7.4.2</version>
		</dependency>
		<dependency>
			<groupId>org.elasticsearch.client</groupId>
			<artifactId>elasticsearch-rest-client</artifactId>
			<version>7.4.2</version>
		</dependency>
	</dependencies>
</dependencyManagement>
2.2 添加ES配置
java 复制代码
@Configuration
public class ElasticsearchConfig {

	/**
     * 配置请求选项
     * 参考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-low-usage-requests.html#java-rest-low-usage-request-options
     */
    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 esRestClient() {
//        RestHighLevelClient highLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.179.101", 9200, "Http"),
//                new HttpHost("192.168.179.101", 9201, "Http")));
        RestHighLevelClient highLevelClient = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.179.101", 9200, "Http")));
        return highLevelClient;
    }

}
2.3 测试及验证整合结果
java 复制代码
@SpringBootTest
public class SearchApplicationTests {

    @Autowired
    private RestHighLevelClient client;

    @Data
    @ToString
    static class Account {
        private int account_number;
        private int balance;
        private String firstname;
        private String lastname;
        private int age;
        private String gender;
        private String address;
        private String employer;
        private String email;
        private String city;
        private String state;
    }

    /**
     * 在new_bank中搜索address中包含mill的所有人的年龄分布以及平均薪资
     */
    @Test
    public void searchData() throws IOException {
        //1,创建检索请求
        SearchRequest searchRequest = new SearchRequest();
        //1.1,指定检索索引
        searchRequest.indices("new_bank");
        //1.2,构造检索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("address", "Mill"));

        //1.2.1,按照年龄分布进行聚合
        TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
        searchSourceBuilder.aggregation(ageAgg);

        //1.2.2,计算平均薪资
        AvgAggregationBuilder avgBalance = AggregationBuilders.avg("avgBalance").field("balance");
        searchSourceBuilder.aggregation(avgBalance);

        System.out.println("检索条件" + searchSourceBuilder);
        searchRequest.source(searchSourceBuilder);

        //2,执行同步检索
        SearchResponse searchResponse = client.search(searchRequest, ElasticsearchConfig.COMMON_OPTIONS);
        System.out.println("执行检索结果" + searchResponse);

        //3,提取命中结果hits
        SearchHits hits = searchResponse.getHits();
        SearchHit[] hitsHits = hits.getHits();
        for (SearchHit hitsHit : hitsHits) {
            String sourceAsString = hitsHit.getSourceAsString();
            Account account = JSONObject.parseObject(sourceAsString, Account.class);
            System.out.println(account);
        }

        //4,提取聚合信息
        Aggregations aggregations = searchResponse.getAggregations();
        Terms ageAggRes = aggregations.get("ageAgg");
        List<? extends Terms.Bucket> aggResBuckets = ageAggRes.getBuckets();
        for (Terms.Bucket aggResBucket : aggResBuckets) {
            System.out.println("年龄:" + aggResBucket.getKeyAsString() + "总和:" + aggResBucket.getDocCount());
        }

        Avg balance = aggregations.get("avgBalance");
        System.out.println(balance.getValue());
    }

    /**
     * https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high-document-index.html
     */
    @Test
    public void testEsAdd() throws IOException {

        //指定索引
        IndexRequest indexRequest = new IndexRequest("users");
        //指定id
        indexRequest.id("1");
        //封装数据
        User user = new User();
        user.setUserName("张三");
        user.setAge(27);
        user.setGender("M");
        String jsonString = JSONObject.toJSONString(user);
        //指定数据类型为JSON
        indexRequest.source(jsonString, XContentType.JSON);

        //执行同步操作
        IndexResponse index = client.index(indexRequest, ElasticsearchConfig.COMMON_OPTIONS);
        System.out.println(index);
    }

    @Data
    class User {
        private String userName;
        private String gender;
        private Integer age;
    }

}
xml 复制代码
kibana

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" : {
          "age" : 27,
          "gender" : "M",
          "userName" : "张三"
        }
      }
    ]
  }
}
相关推荐
Iced_Sheep44 分钟前
干掉 if else 之策略模式
后端·设计模式
XINGTECODE1 小时前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
程序猿进阶1 小时前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺1 小时前
Spring Boot框架Starter组件整理
java·spring boot·后端
凡人的AI工具箱2 小时前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
小码的头发丝、2 小时前
Spring Boot 注解
java·spring boot
先天牛马圣体2 小时前
如何提升大型AI模型的智能水平
后端
午觉千万别睡过2 小时前
RuoYI分页不准确问题解决
spring boot
java亮小白19972 小时前
Spring循环依赖如何解决的?
java·后端·spring
2301_811274312 小时前
大数据基于Spring Boot的化妆品推荐系统的设计与实现
大数据·spring boot·后端