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" : "张三"
        }
      }
    ]
  }
}
相关推荐
舒一笑25 分钟前
AI 系统落地难的,从来不只是模型:一次企业级部署实施复盘
运维·后端·程序员
心勤则明41 分钟前
Spring AI Alibaba Skills 的渐进式披露与热更新实战
java·后端·spring
霸道流氓气质1 小时前
SpringBoot中使用SpringAIAlibaba框架集成阿里云百炼实现AI快速对话入门示例
人工智能·spring boot·阿里云
金融数据出海1 小时前
java对接美股股票api涵盖实时行情、K 线、指数等核心接口。
后端
认真的小羽❅1 小时前
从入门到精通:Spring Boot 整合 MyBatis 全攻略
spring boot·后端·mybatis
摆烂工程师2 小时前
教你如何查询 Codex 最新额度是多少,以及 ChatGPT Pro、Plus、Business 最新额度变化
前端·后端·ai编程
任聪聪2 小时前
我做了一款通用本地化部署模型运行调度器,运行所有大模型!
后端
开发者如是说2 小时前
可能是最好用的多语言管理工具
android·前端·后端
老纪的技术唠嗑局2 小时前
告别OpenClaw配置丢失——Mindkeeper内测版邀测
大数据·elasticsearch·搜索引擎
Elasticsearch2 小时前
使用 Elasticsearch + Jina embeddings 进行无监督文档聚类
elasticsearch