ElasticSearch进阶篇之ElasticSearch-Rest-Client在SpringBoot项目中实战

网友投稿 879 2022-05-29

1.ES 的Java API两种方式

elasticsearch 的API 分为 REST Client API(http请求形式)以及 transportClient

API两种。相比来说transportClient API效率更高,transportClient

是通过Elasticsearch内部RPC的形式进行请求的,连接可以是一个长连接,相当于是把客户端的请求当成

Elasticsearch 集群的一个节点,当然 REST Client API 也支持http

keepAlive形式的长连接,只是非内部RPC形式。但是从Elasticsearch 7 后就会移除transportClient

。主要原因是transportClient 难以向下兼容版本。

1.1 9300[TCP]

利用9300端口的是spring-data-elasticsearch:transport-api.jar,但是这种方式因为对应的SpringBoot版本不一致,造成对应的transport-api.jar也不同,不能适配es的版本,而且ElasticSearch7.x中已经不推荐使用了,ElasticSearch 8之后更是废弃了,所以我们不做过多的介绍

1.2 9200[HTTP]

基于9200端口的方式也有多种

JsetClient:非官方,更新缓慢

RestTemplate:模拟发送Http请求,ES很多的操作需要我们自己来封装,效率低

HttpClient:和上面的情况一样

ElasticSearch-Rest-Client:官方的RestClient,封装了ES的操作,API层次分明,易于上手。

JavaAPIClient 7.15版本后推荐

2.ElasticSearch-Rest-Client整合

2.1 创建检索的服务

我们在商城服务中创建一个检索的SpringBoot服务

添加对应的依赖:官方地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-maven.html#java-rest-high-getting-started-maven-maven

公共依赖不要忘了,同时我们在公共依赖中依赖了MyBatisPlus所以我们需要在search服务中排除数据源,不然启动报错

然后我们需要把这个服务注册到Nacos注册中心中,这块操作了很多遍,不重复

添加对应的ElasticSearch的配置类

/** * ElasticSearch的配置类 */ @Configuration public class MallElasticSearchConfiguration { @Bean public RestHighLevelClient restHighLevelClient(){ RestClientBuilder builder = RestClient.builder(new HttpHost("192.168.56.100", 9200, "http")); RestHighLevelClient client = new RestHighLevelClient(builder); return client; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

测试:

2.2 测试保存文档

设置RequestOptions

我们就在ElasticSearch的配置文件中设置

保存数据

然后就可以结合官方文档来实现文档数据的存储

package com.msb.mall.mallsearch; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.util.JSONPObject; import com.msb.mall.mallsearch.config.MallElasticSearchConfiguration; import lombok.Data; 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.json.JSONObject; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class MallSearchApplicationTests { @Autowired private RestHighLevelClient client; @Test void contextLoads() { System.out.println("--->"+client); } /** * 测试保存文档 */ @Test void saveIndex() throws Exception { IndexRequest indexRequest = new IndexRequest("system"); indexRequest.id("1"); // indexRequest.source("name","bobokaoya","age",18,"gender","男"); User user = new User(); user.setName("bobo"); user.setAge(22); user.setGender("男"); // 用Jackson中的对象转json数据 ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(user); indexRequest.source(json, XContentType.JSON); // 执行操作 IndexResponse index = client.index(indexRequest, MallElasticSearchConfiguration.COMMON_OPTIONS); // 提取有用的返回信息 System.out.println(index); } @Data class User{ private String name; private Integer age; private String gender; } }

1

2

3

4

5

6

7

8

9

10

ElasticSearch进阶篇之ElasticSearch-Rest-Client在SpringBoot项目中实战

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

之后成功

2.3 检索操作

参考官方文档可以获取到处理各种检索情况的API

案例1:检索出所有的bank索引的所有文档

@Test void searchIndexAll() throws IOException { // 1.创建一个 SearchRequest 对象 SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("bank"); // 设置我们要检索的数据对应的索引库 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); /*sourceBuilder.query(); sourceBuilder.from(); sourceBuilder.size(); sourceBuilder.aggregation();*/ searchRequest.source(sourceBuilder); // 2.如何执行检索操作 SearchResponse response = client.search(searchRequest, MallElasticSearchConfiguration.COMMON_OPTIONS); // 3.获取检索后的响应对象,我们需要解析出我们关心的数据 System.out.println("ElasticSearch检索的信息:"+response); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

案例2:根据address全文检索

@Test void searchIndexByAddress() throws IOException { // 1.创建一个 SearchRequest 对象 SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("bank"); // 设置我们要检索的数据对应的索引库 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 查询出bank下 address 中包含 mill的记录 sourceBuilder.query(QueryBuilders.matchQuery("address","mill")); searchRequest.source(sourceBuilder); // System.out.println(searchRequest); // 2.如何执行检索操作 SearchResponse response = client.search(searchRequest, MallElasticSearchConfiguration.COMMON_OPTIONS); // 3.获取检索后的响应对象,我们需要解析出我们关心的数据 System.out.println("ElasticSearch检索的信息:"+response); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

案例3:嵌套的聚合操作:检索出bank下的年龄分布和每个年龄段的平均薪资

/** * 聚合:嵌套聚合 * @throws IOException */ @Test void searchIndexAggregation() throws IOException { // 1.创建一个 SearchRequest 对象 SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("bank"); // 设置我们要检索的数据对应的索引库 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 查询出bank下 所有的文档 sourceBuilder.query(QueryBuilders.matchAllQuery()); // 聚合 aggregation // 聚合bank下年龄的分布和每个年龄段的平均薪资 AggregationBuilder aggregationBuiler = AggregationBuilders.terms("ageAgg") .field("age") .size(10); // 嵌套聚合 aggregationBuiler.subAggregation(AggregationBuilders.avg("balanceAvg").field("balance")); sourceBuilder.aggregation(aggregationBuiler); sourceBuilder.size(0); // 聚合的时候就不用显示满足条件的文档内容了 searchRequest.source(sourceBuilder); System.out.println(sourceBuilder); // 2.如何执行检索操作 SearchResponse response = client.search(searchRequest, MallElasticSearchConfiguration.COMMON_OPTIONS); // 3.获取检索后的响应对象,我们需要解析出我们关心的数据 System.out.println(response); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

案例4:并行的聚合操作:查询出bank下年龄段的分布和总的平均薪资

/** * 聚合 * @throws IOException */ @Test void searchIndexAggregation1() throws IOException { // 1.创建一个 SearchRequest 对象 SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("bank"); // 设置我们要检索的数据对应的索引库 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 查询出bank下 所有的文档 sourceBuilder.query(QueryBuilders.matchAllQuery()); // 聚合 aggregation // 聚合bank下年龄的分布和平均薪资 AggregationBuilder aggregationBuiler = AggregationBuilders.terms("ageAgg") .field("age") .size(10); sourceBuilder.aggregation(aggregationBuiler); // 聚合平均年龄 AvgAggregationBuilder balanceAggBuilder = AggregationBuilders.avg("balanceAgg").field("age"); sourceBuilder.aggregation(balanceAggBuilder); sourceBuilder.size(0); // 聚合的时候就不用显示满足条件的文档内容了 searchRequest.source(sourceBuilder); System.out.println(sourceBuilder); // 2.如何执行检索操作 SearchResponse response = client.search(searchRequest, MallElasticSearchConfiguration.COMMON_OPTIONS); // 3.获取检索后的响应对象,我们需要解析出我们关心的数据 System.out.println(response); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

案例5:处理检索后的结果

@Test void searchIndexResponse() throws IOException { // 1.创建一个 SearchRequest 对象 SearchRequest searchRequest = new SearchRequest(); searchRequest.indices("bank"); // 设置我们要检索的数据对应的索引库 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 查询出bank下 address 中包含 mill的记录 sourceBuilder.query(QueryBuilders.matchQuery("address","mill")); searchRequest.source(sourceBuilder); // System.out.println(searchRequest); // 2.如何执行检索操作 SearchResponse response = client.search(searchRequest, MallElasticSearchConfiguration.COMMON_OPTIONS); // 3.获取检索后的响应对象,我们需要解析出我们关心的数据 // System.out.println("ElasticSearch检索的信息:"+response); RestStatus status = response.status(); TimeValue took = response.getTook(); SearchHits hits = response.getHits(); TotalHits totalHits = hits.getTotalHits(); TotalHits.Relation relation = totalHits.relation; long value = totalHits.value; float maxScore = hits.getMaxScore(); // 相关性的最高分 SearchHit[] hits1 = hits.getHits(); for (SearchHit documentFields : hits1) { /*"_index" : "bank", "_type" : "account", "_id" : "970", "_score" : 5.4032025*/ //documentFields.getIndex(),documentFields.getType(),documentFields.getId(),documentFields.getScore(); String json = documentFields.getSourceAsString(); //System.out.println(json); // JSON字符串转换为 Object对象 ObjectMapper mapper = new ObjectMapper(); Account account = mapper.readValue(json, Account.class); System.out.println("account = " + account); } //System.out.println(relation.toString()+"--->" + value + "--->" + status); } @ToString @Data 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; }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

数据的结果:

Elasticsearch Spring Boot

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:uni-id入门(五)---基础操作(上)
下一篇:Java高性能编程实战 - 线程通信
相关文章