• 使用JavaRestClient查询文档&排序、分页、高亮


    可以参考着“利用JavaRestClient实现文档的CRUD(从mysql数据库转移到es)”来看

    http://t.csdn.cn/SP5nx

    1、解析响应的方法

    1. private void handleResponse(SearchResponse response) {
    2. // 4.解析响应
    3. SearchHits searchHits = response.getHits();
    4. // 4.1.获取总条数
    5. long total = searchHits.getTotalHits().value;
    6. System.out.println("共搜索到" + total + "条数据");
    7. // 4.2.文档数组
    8. SearchHit[] hits = searchHits.getHits();
    9. // 4.3.遍历
    10. for (SearchHit hit : hits) {
    11. // 获取文档source
    12. String json = hit.getSourceAsString();
    13. // 反序列化
    14. //HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    15. //System.out.println("hotelDoc = " + hotelDoc);
    16. System.out.println(json);
    17. }
    18. }

    2、无条件查找

    1. package cn.itcast.hotel;
    2. import cn.itcast.hotel.pojo.HotelDoc;
    3. import cn.itcast.hotel.service.IHotelService;
    4. import cn.itcast.hotel.utils.HotelConstants;
    5. import com.alibaba.fastjson.JSON;
    6. import lombok.extern.slf4j.Slf4j;
    7. import org.apache.http.HttpHost;
    8. import org.elasticsearch.action.search.SearchRequest;
    9. import org.elasticsearch.action.search.SearchResponse;
    10. import org.elasticsearch.client.RequestOptions;
    11. import org.elasticsearch.client.RestClient;
    12. import org.elasticsearch.client.RestHighLevelClient;
    13. import org.elasticsearch.client.indices.CreateIndexRequest;
    14. import org.elasticsearch.common.xcontent.XContentType;
    15. import org.elasticsearch.index.query.QueryBuilders;
    16. import org.elasticsearch.search.SearchHit;
    17. import org.elasticsearch.search.SearchHits;
    18. import org.junit.jupiter.api.Test;
    19. import org.springframework.beans.factory.annotation.Autowired;
    20. import org.springframework.boot.test.context.SpringBootTest;
    21. /**
    22. * 酒店查询测试
    23. *
    24. * @author ning
    25. * @since 2022/12/5 22:45
    26. */
    27. @Slf4j
    28. @SpringBootTest
    29. public class HotelSearchTest {
    30. @Autowired
    31. private IHotelService hotelService;
    32. @Test
    33. void testMatchAll() throws Exception {
    34. //初始化RestHighLevelClient:
    35. RestHighLevelClient client = new RestHighLevelClient(
    36. RestClient.builder(HttpHost.create("http://192.168.177.132:9200"))
    37. );
    38. //创建请求
    39. //hotel 是查询的文档名
    40. SearchRequest request = new SearchRequest("hotel");
    41. //设置参数
    42. //QueryBuilders 工具类
    43. //matchAllQuery() 无条件查询
    44. request.source()
    45. .query(QueryBuilders.matchAllQuery());
    46. //执行请求
    47. //第一个参数:创建的请求,第二个参数:是否还有其他的选项,一般选DEFAULT
    48. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    49. //解析响应
    50. handleResponse(response);
    51. }
    52. private void handleResponse(SearchResponse response) {
    53. // 4.解析响应
    54. SearchHits searchHits = response.getHits();
    55. // 4.1.获取总条数
    56. long total = searchHits.getTotalHits().value;
    57. System.out.println("共搜索到" + total + "条数据");
    58. // 4.2.文档数组
    59. SearchHit[] hits = searchHits.getHits();
    60. // 4.3.遍历
    61. for (SearchHit hit : hits) {
    62. // 获取文档source
    63. String json = hit.getSourceAsString();
    64. // 反序列化
    65. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    66. System.out.println("hotelDoc = " + hotelDoc);
    67. }
    68. }
    69. }

     3、全文检索查询

     单字段全文检索查询:match查询

    代码和上边无条件查询基本一致,只是需要把查询条件换一下

    1. //设置参数
    2. //QueryBuilders 工具类
    3. request.source()
    4. .query(
    5. //QueryBuilders.matchAllQuery() //无条件查询
    6. QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
    7. );

     

      多字段全文检索查询:multi_match查询

    代码和上边无条件查询基本一致,只是需要把查询条件换一下

    1. //设置参数
    2. //QueryBuilders 工具类
    3. request.source()
    4. .query(
    5. //QueryBuilders.matchAllQuery() //无条件查询
    6. //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
    7. QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
    8. );

     

     4、精确查询

     精确查询主要是两者:

    • term:词条精确匹配

    • range:范围查询

    term:词条精确匹配

    1. //设置参数
    2. //QueryBuilders 工具类
    3. request.source()
    4. .query(
    5. //QueryBuilders.matchAllQuery() //无条件查询
    6. //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
    7. //QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
    8. QueryBuilders.termQuery("city","北京")//词条精确匹配
    9. );

     range:范围查询

    1. //设置参数
    2. //QueryBuilders 工具类
    3. request.source()
    4. .query(
    5. //QueryBuilders.matchAllQuery() //无条件查询
    6. //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
    7. //QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
    8. //QueryBuilders.termQuery("city","北京")//term:词条精确匹配
    9. QueryBuilders.rangeQuery("price").gte(100).lte(200)//range:范围查询
    10. );

     

     5、复合查询-boolean query

    布尔查询是用must、must_not、filter等方式组合其它查询,代码示例如下:

     

    1. //设置参数
    2. //QueryBuilders 工具类
    3. request.source()
    4. .query(
    5. //QueryBuilders.matchAllQuery() //无条件查询
    6. //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
    7. //QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
    8. //QueryBuilders.termQuery("city","北京")//term:词条精确匹配
    9. //QueryBuilders.rangeQuery("price").gte(100).lte(200)//range:范围查询
    10. //boolQuery 布尔查询
    11. //其中的子查询包括酒店名字为如家,并且价格在100~200之间的
    12. //子查询可以有多个
    13. QueryBuilders.boolQuery()
    14. .must(QueryBuilders.matchQuery("name", "如家"))
    15. .filter(QueryBuilders.rangeQuery("price").gte(100).lte(200))
    16. );

     

     6、对查询结果进行排序和分页

    计算分页的公式:(当前页-1)*每页显示多少条数据,可以得出要从哪一条数据开始查

    1. //排序
    2. //按照价格升序
    3. request.source().sort("price", SortOrder.ASC);
    4. //分页
    5. //一般由前端返回分页的数据
    6. int pageNo = 1;//当前页
    7. int pageSize = 2;//每页显示多少数据
    8. request.source().from((pageNo-1)*pageSize).size(pageSize);

     

     7、对查询结果高亮显示

    高亮的代码与之前代码差异较大,有两点:

    • 查询的DSL:其中除了查询条件,还需要添加高亮条件,同样是与query同级。

    • 结果解析:结果除了要解析_source文档数据,还要解析高亮结果

    7.1 高亮请求构建

    高亮查询必须使用全文检索查询,并且要有搜索关键字,将来才可以对关键字高亮。

    1. //高亮的请求
    2. //将酒店名中的如家两个字高亮显示,
    3. //HighlightBuilder 工具类
    4. //field 在哪个字段使用高亮显示
    5. //requireFieldMatch 如果查询的字段和高亮显示使用的字段比一样,需要指定为false
    6. //建议就算一样,也写上,不会有影响
    7. request.source().highlighter(
    8. new HighlightBuilder().field("name").requireFieldMatch(false)
    9. );

     7.3 高亮结果解析

    高亮的结果与查询的文档结果默认是分离的,并不在一起。

    因此解析高亮的代码需要额外处理:

     代码解读:

    • 第一步:从结果中获取source。hit.getSourceAsString(),这部分是非高亮结果,json字符串。还需要反序列为HotelDoc对象

    • 第二步:获取高亮结果。hit.getHighlightFields(),返回值是一个Map,key是高亮字段名称,值是HighlightField对象,代表高亮值

    • 第三步:从map中根据高亮字段名称,获取高亮字段值对象HighlightField

    • 第四步:从HighlightField中获取Fragments,并且转为字符串。这部分就是真正的高亮字符串了

    • 第五步:用高亮的结果替换HotelDoc中的非高亮结果

    1. private void handleResponse(SearchResponse response) {
    2. // 4.解析响应
    3. SearchHits searchHits = response.getHits();
    4. // 4.1.获取总条数
    5. long total = searchHits.getTotalHits().value;
    6. System.out.println("共搜索到" + total + "条数据");
    7. // 4.2.文档数组
    8. SearchHit[] hits = searchHits.getHits();
    9. // 4.3.遍历
    10. for (SearchHit hit : hits) {
    11. // 获取文档source
    12. String json = hit.getSourceAsString();
    13. System.out.println(json);
    14. 反序列化
    15. //HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
    16. // 获取高亮结果
    17. Map highlightFields = hit.getHighlightFields();
    18. if (!CollectionUtils.isEmpty(highlightFields)) {
    19. // 根据字段名获取高亮结果
    20. HighlightField highlightField = highlightFields.get("name");
    21. if (highlightField != null && highlightField.getFragments().length > 0) {
    22. // 获取高亮值
    23. String name = highlightField.getFragments()[0].string();
    24. 覆盖非高亮结果
    25. //hotelDoc.setName(name);
    26. System.out.println("高亮处理后的酒店名称:" + name);
    27. }
    28. }
    29. }
    30. }

     

     

  • 相关阅读:
    代码随想录算法训练营第五天| 哈希表理论基础、242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和
    qml入门教程:qml的初步使用
    Spark获取DataFrame中列的方式--col,$,column,apply
    【shell】2> /dev/null 和 1> /dev/null 和 > /dev/null 2>&1
    网络编程:使用UDP协议实现服务器与客户端的交互
    SSM+美食论坛系统 毕业设计-附源码191023
    SQL Server 数据库创建与删除
    idea一些常用的快捷键
    java计算机毕业设计医院远程诊断系统源代码+系统+数据库+lw文档
    深度学习基础:循环神经网络中的长期依赖问题
  • 原文地址:https://blog.csdn.net/LINING_GG/article/details/128194933