• 实用篇-ES-RestClient查询文档


    一、快速入门

    上面的查询文档都是依赖kibana,在浏览器页面使用DSL语句去查询es,如何用java去查询es里面的文档(数据)呢
    我们通过match_all查询来演示基本的API,注意下面演示的是 'match_all查询,也叫基础查询'
    首先保证你已经做好了 '实用篇-ES-环境搭建' ,创建了名为gghotel的索引库,然后开始下面的操作。如果需要浏览器操作es,那就不需要启动kibana容器

    在进行下面的操作之前,确保你已经看了前面 '实用篇-ES-RestClient操作文档' 学的 '1. RestClient案例准备',然后在进行下面的操作


    第一步: 在src/test/java/cn.itcast.hotel目录新建HotelSearchTest类,写入如下

    1. package cn.itcast.hotel;
    2. import cn.itcast.hotel.service.IHotelService;
    3. import org.apache.http.HttpHost;
    4. import org.elasticsearch.action.search.SearchRequest;
    5. import org.elasticsearch.action.search.SearchResponse;
    6. import org.elasticsearch.client.RequestOptions;
    7. import org.elasticsearch.client.RestClient;
    8. import org.elasticsearch.client.RestHighLevelClient;
    9. import org.elasticsearch.index.query.QueryBuilders;
    10. import org.junit.jupiter.api.AfterEach;
    11. import org.junit.jupiter.api.BeforeEach;
    12. import org.junit.jupiter.api.Test;
    13. import org.springframework.beans.factory.annotation.Autowired;
    14. import org.springframework.boot.test.context.SpringBootTest;
    15. import java.io.IOException;
    16. @SpringBootTest
    17. public class HotelIndexTest2 {
    18. private RestHighLevelClient client;
    19. @Autowired
    20. private IHotelService hotelService;
    21. @Test
    22. void init(){
    23. System.out.println(client);
    24. }
    25. @BeforeEach
    26. void setUp(){
    27. this.client = new RestHighLevelClient(RestClient.builder(
    28. //指定你Centos7部署的es的主机地址
    29. HttpHost.create("http://192.168.229.129:9200")
    30. ));
    31. }
    32. @AfterEach
    33. void tearDown() throws IOException {
    34. this.client.close();
    35. }
    36. @Test
    37. void testMatchAll() throws IOException {
    38. //准备Request
    39. SearchRequest request = new SearchRequest("hotel");
    40. //组织DSL参数
    41. request.source().query(QueryBuilders.matchAllQuery());
    42. //发送请求,得到响应结果
    43. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    44. System.out.println(response);
    45. }
    46. }

    第二步: 把控制台里面我们需要的数据解析出来。返回的数据很多,我们主要是解析hits里面的数据就行了

    把HotelSearchTest类修改为如下,主要的修改是sout之前做了一次解析,拿到我们想要的数据

    1. package cn.itcast.hotel;
    2. import cn.itcast.hotel.pojo.HotelDoc;
    3. import cn.itcast.hotel.service.IHotelService;
    4. import com.alibaba.fastjson.JSON;
    5. import org.apache.http.HttpHost;
    6. import org.elasticsearch.action.search.SearchRequest;
    7. import org.elasticsearch.action.search.SearchResponse;
    8. import org.elasticsearch.client.RequestOptions;
    9. import org.elasticsearch.client.RestClient;
    10. import org.elasticsearch.client.RestHighLevelClient;
    11. import org.elasticsearch.index.query.QueryBuilders;
    12. import org.elasticsearch.search.SearchHit;
    13. import org.elasticsearch.search.SearchHits;
    14. import org.junit.jupiter.api.AfterEach;
    15. import org.junit.jupiter.api.BeforeEach;
    16. import org.junit.jupiter.api.Test;
    17. import org.springframework.beans.factory.annotation.Autowired;
    18. import org.springframework.boot.test.context.SpringBootTest;
    19. import java.io.IOException;
    20. @SpringBootTest
    21. public class HotelIndexTest2 {
    22. private RestHighLevelClient client;
    23. @Autowired
    24. private IHotelService hotelService;
    25. @Test
    26. void init(){
    27. System.out.println(client);
    28. }
    29. @BeforeEach
    30. void setUp(){
    31. this.client = new RestHighLevelClient(RestClient.builder(
    32. //指定你Centos7部署的es的主机地址
    33. HttpHost.create("http://192.168.229.129:9200")
    34. ));
    35. }
    36. @AfterEach
    37. void tearDown() throws IOException {
    38. this.client.close();
    39. }
    40. @Test
    41. void testMatchAll() throws IOException {
    42. //准备Request
    43. SearchRequest request = new SearchRequest("hotel");
    44. //组织DSL参数
    45. request.source().query(QueryBuilders.matchAllQuery());
    46. //发送请求,得到响应结果
    47. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    48. //下面为逐层解析json数据
    49. SearchHits searchHits = response.getHits();
    50. long total = searchHits.getTotalHits().value;
    51. System.out.println("共有" + total + "条数据");
    52. SearchHit[] hits = searchHits.getHits();
    53. for (SearchHit hit : hits) {
    54. String json = hit.getSourceAsString();
    55. //反系列化
    56. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    57. System.out.println("hotelDoc = " + hotelDoc);
    58. }
    59. }
    60. }

    二、match的三种查询

    我们刚刚在第一节演示的是 match_all(也叫基本查询) 查询,下面将演示 match(也叫单字段查询) 和 multi_match(也叫多字段查询) 查询

    【match 查询,也叫单字段查询】

    在HotelSearchTest类添加如下

    1. @Test
    2. void testMatch() throws IOException {
    3. //准备Request
    4. SearchRequest request = new SearchRequest("hotel");
    5. //组织DSL参数
    6. request.source().query(QueryBuilders.matchQuery("name","如家"));
    7. //发送请求,得到响应结果
    8. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    9. //下面为逐层解析json数据
    10. SearchHits searchHits = response.getHits();
    11. long total = searchHits.getTotalHits().value;
    12. System.out.println("共有" + total + "条数据");
    13. SearchHit[] hits = searchHits.getHits();
    14. for (SearchHit hit : hits) {
    15. String json = hit.getSourceAsString();
    16. //反系列化
    17. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    18. System.out.println("hotelDoc = " + hotelDoc);
    19. }
    20. }

    【multi_match 查询,也叫多字段查询】

    在HotelSearchTest类添加如下

    1. @Test
    2. void testMatch() throws IOException {
    3. //准备Request
    4. SearchRequest request = new SearchRequest("hotel");
    5. //组织DSL参数
    6. request.source().query(QueryBuilders.multiMatchQuery("如家","name","business"));
    7. //发送请求,得到响应结果
    8. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    9. //下面为逐层解析json数据
    10. SearchHits searchHits = response.getHits();
    11. long total = searchHits.getTotalHits().value;
    12. System.out.println("共有" + total + "条数据");
    13. SearchHit[] hits = searchHits.getHits();
    14. for (SearchHit hit : hits) {
    15. String json = hit.getSourceAsString();
    16. //反系列化
    17. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    18. System.out.println("hotelDoc = " + hotelDoc);
    19. }
    20. }

    总结: 要构建查询条件,只要记住一个QueryBuilders类即可

    三、解析代码的抽取

    我们发现对于 match、multi_match、match_all 查询,的解析部分的代码都是相同的,所以我们可以对解析部分的代码进行抽取,如下

    快捷键ctrl + alt + M

    1. private void handleResponse(SearchResponse response) {
    2. //下面为逐层解析json数据
    3. SearchHits searchHits = response.getHits();
    4. long total = searchHits.getTotalHits().value;
    5. System.out.println("共有" + total + "条数据");
    6. SearchHit[] hits = searchHits.getHits();
    7. for (SearchHit hit : hits) {
    8. String json = hit.getSourceAsString();
    9. //反系列化
    10. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    11. System.out.println("hotelDoc = " + hotelDoc);
    12. }
    13. }

    之后我们在test中只专注于json的获取,解析的任务交给这段代码 

    四、bool和term、rang精确查询

    原理同上

    我们直接演示bool复合查询 

     

    1. @Test
    2. void testBool() throws IOException {
    3. //准备Request
    4. SearchRequest request = new SearchRequest("hotel");
    5. //组织DSL参数
    6. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    7. boolQuery.must(QueryBuilders.termQuery("city","杭州"));
    8. boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
    9. request.source().query(boolQuery);
    10. //发送请求,得到响应结果
    11. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    12. handleResponse(response);
    13. }

    五、排序和分页

    1. @Test
    2. void testPageAndSort() throws IOException {
    3. int pageNum = 1;
    4. int pageSize = 5;
    5. //准备Request
    6. SearchRequest request = new SearchRequest("hotel");
    7. //组织DSL参数
    8. //查询所有
    9. request.source().query(QueryBuilders.matchAllQuery());
    10. //排序
    11. request.source().sort("price", SortOrder.ASC);
    12. //分页
    13. request.source().from(pageNum - 1).size(pageSize);
    14. //发送请求,得到响应结果
    15. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    16. handleResponse(response);
    17. }

    六、高亮显示

     高亮API包括请求DSL构建和结果解析两部分,API和对应的DSL语句如下图,下图只是构建,再下面还有解析,高亮必须由构建+解析才能实现

    解析,如下图 

    1. @Test
    2. void testHighLight() throws IOException {
    3. //准备Request
    4. SearchRequest request = new SearchRequest("hotel");
    5. //组织DSL参数
    6. //查询所有
    7. request.source().query(QueryBuilders.matchQuery("name","如家"));
    8. //设置高亮匹配方式
    9. request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
    10. //发送请求,得到响应结果
    11. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    12. //下面为逐层解析json数据
    13. SearchHits searchHits = response.getHits();
    14. long total = searchHits.getTotalHits().value;
    15. System.out.println("共有" + total + "条数据");
    16. SearchHit[] hits = searchHits.getHits();
    17. for (SearchHit hit : hits) {
    18. String json = hit.getSourceAsString();
    19. //反系列化
    20. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    21. //解析,获取高亮结果
    22. Map highlightFields = hit.getHighlightFields();
    23. if(!CollectionUtils.isEmpty(highlightFields)){
    24. //根据字段名获取高亮结果
    25. HighlightField highlightField = highlightFields.get("name");
    26. //判断高亮字段不为空
    27. if(highlightField!=null){
    28. //获取高亮值
    29. String name = highlightField.getFragments()[0].string();
    30. //覆盖非高亮结果
    31. hotelDoc.setName(name);
    32. }
    33. }
    34. //最终输出
    35. System.out.println("hotelDoc = " + hotelDoc);
    36. }
    37. }

  • 相关阅读:
    Activiti工作流入门
    「实战应用」如何用DHTMLX将上下文菜单集成到JavaScript甘特图中(一)
    恢复受感染的数据:如何应对.360勒索病毒的策略
    极简idea下git操作(一)
    中科数安|公司办公终端、电脑文件数据 \ 资料防泄密系统
    iNFTnews | 佳士得推出风险投资部门,瞄准Web3和元宇宙产业
    leetcode 374. Guess Number Higher or Lower(猜数字)
    dependencies和devDependencies的区别
    虚幻4学习笔记(14)界面切换、局域网联机
    Docker 启动容器
  • 原文地址:https://blog.csdn.net/m0_63732435/article/details/134450494