SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)

文章目录

  • [1. 环境准备](#1. 环境准备)
  • [1. 查询全部](#1. 查询全部)
  • [2. 根据 name 查询 match 分词查询](#2. 根据 name 查询 match 分词查询)
  • [3. 根据 name 和 品牌查询 multiMatch 分词查询](#3. 根据 name 和 品牌查询 multiMatch 分词查询)
  • [4. 根据 brand 查询 match 分词查询](#4. 根据 brand 查询 match 分词查询)
  • [5. 按照价格 范围查询](#5. 按照价格 范围查询)
  • [6. 精确查询](#6. 精确查询)
  • [7. boolQuery](#7. boolQuery)
  • [8. 分页](#8. 分页)
  • [9. 高亮查询](#9. 高亮查询)
  • [9. 公共解析](#9. 公共解析)

上一节讲述了 SpringBoot 实现 elasticsearch 索引操作,这一章节讲述 SpringBoot 实现 elasticsearch 查询操作。

1. 环境准备

案例用到的索引库结构

json 复制代码
PUT /hotel
{
  "mappings": {
    "properties": {
      "id": {
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_max_word",
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword",
        "copy_to": "all"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

1. 查询全部

java 复制代码
@GetMapping("/searchAll")
public List<HotelDoc> searchAll() throws Exception {
    //1.创建请求语义对象
    SearchRequest searchRequest = new SearchRequest("索引名称");
    // QueryBuilders: 构建查询类型
    searchRequest.source().query(QueryBuilders.matchAllQuery());

    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

    return handleResponse(searchResponse);
}

2. 根据 name 查询 match 分词查询

java 复制代码
 @GetMapping("/searchByName/{name}")
public List<HotelDoc> searchByName(@PathVariable("name") String name) 
	throws Exception {
    //1.创建请求语义对象
    SearchRequest searchRequest = new SearchRequest("索引名称");
    // QueryBuilders: 构建查询类型
    searchRequest.source().query(QueryBuilders.matchQuery("name", name));

    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

    return handleResponse(searchResponse);
}

3. 根据 name 和 品牌查询 multiMatch 分词查询

java 复制代码
@GetMapping("/searchByNameAndBrand/{name}")
public List<HotelDoc> searchByNameAndBrand(@PathVariable("name") String name) throws Exception {
    //1.创建请求语义对象
    SearchRequest searchRequest = new SearchRequest("索引名称");
    // QueryBuilders: 构建查询类型
    searchRequest.source().query(QueryBuilders.multiMatchQuery(name,"name","brand"));
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

    return handleResponse(searchResponse);
}

4. 根据 brand 查询 match 分词查询

java 复制代码
@GetMapping("/searchByBrand/{name}")
public List<HotelDoc> searchByBrand(@PathVariable("name") String name) throws Exception {
    //1.创建请求语义对象
    SearchRequest searchRequest = new SearchRequest("索引名称");
    // QueryBuilders: 构建查询类型
    searchRequest.source().query(QueryBuilders.matchQuery("brand", name));
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

    return handleResponse(searchResponse);
}

5. 按照价格 范围查询

java 复制代码
 @GetMapping("/searchByPrice/{low}/{high}")
public List<HotelDoc> searchByPrice(@PathVariable("low") String low, @PathVariable("high") String high) throws Exception {
    //1.创建请求语义对象
    SearchRequest searchRequest = new SearchRequest("索引名称");
    // QueryBuilders: 构建查询类型
    searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(low).lte(high));
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

    return handleResponse(searchResponse);
}

6. 精确查询

java 复制代码
@GetMapping("/termQueryCity/{city}")
public List<HotelDoc> termQueryCity(@PathVariable("city") String city) throws Exception {
    //1.创建请求语义对象
    SearchRequest searchRequest = new SearchRequest("索引名称");
    // QueryBuilders: 构建查询类型
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
	//searchSourceBuilder.query(QueryBuilders.termQuery("city", city)); 这行有点小问题
	//	https://zhuanlan.zhihu.com/p/270426807 参考
    searchSourceBuilder.query(QueryBuilders.termQuery("city.keyword", city));

    searchRequest.source(searchSourceBuilder);
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

    return handleResponse(searchResponse);
}

7. boolQuery

java 复制代码
@GetMapping("/testBool")
public List<HotelDoc> testBool() throws Exception {
    // 1.准备Request
    SearchRequest request = new SearchRequest("索引名称");
    // 2.准备DSL
    // 2.1.准备BooleanQuery
    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    // 2.2.添加term
    boolQuery.must(QueryBuilders.termQuery("city.keyword", "杭州"));
    // 2.3.添加range
    boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));

    request.source().query(boolQuery);
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    return handleResponse(response);
}

8. 分页

java 复制代码
 @GetMapping("/testPageAndSort/{currentPage}/{pageSize}")
public List<HotelDoc> testPageAndSort(@PathVariable("currentPage") Integer currentPage, @PathVariable("pageSize") Integer pageSize) throws Exception {
    // 页码,每页大小

    // 1.准备Request
    SearchRequest request = new SearchRequest("索引名称");
    // 2.准备DSL
    // 2.1.query
    request.source().query(QueryBuilders.matchAllQuery());
    // 2.2.排序 sort
    request.source().sort("price", SortOrder.ASC);
    // 2.3.分页 from、size
    request.source().from((currentPage - 1) * pageSize).size(pageSize);
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    return handleResponse(response);
}

9. 高亮查询

java 复制代码
 @GetMapping("/testHighlight/{name}")
void testHighlight(@PathVariable("name") String name) throws Exception {
    // 1.准备Request
    SearchRequest request = new SearchRequest("索引名称");
    // 2.准备DSL
    // 2.1.query
    request.source().query(QueryBuilders.matchQuery("name", name));
    // 2.2.高亮
    request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
    // 3.发送请求
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    // 4.解析响应
    handleResponse2(response);
}

9. 公共解析

java 复制代码
private List<HotelDoc> handleResponse(SearchResponse response) throws Exception {
    // 获取命中的所有内容
    SearchHits searchHits = response.getHits();
    // 获取命中的总条数
    long count = searchHits.getTotalHits().value;
    System.out.println("命中的条数为: "+ count);
    // 获取命中的文档对象数组
    SearchHit[] hits = searchHits.getHits();
    List<HotelDoc> docList = new ArrayList<>();
    for (SearchHit hit : hits) {
        // 解析每一个hit对象得到对应的文档数据
        String json = hit.getSourceAsString();
        //  HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        docList.add(JSON.parseObject(json, HotelDoc.class));
    }
    //destroy();
    return docList;
}


private void handleResponse2(SearchResponse response) {
    // 4.解析响应
    SearchHits searchHits = response.getHits();
    // 4.1.获取总条数
    long total = searchHits.getTotalHits().value;
    System.out.println("共搜索到" + total + "条数据");
    // 4.2.文档数组
    SearchHit[] hits = searchHits.getHits();
    // 4.3.遍历
    for (SearchHit hit : hits) {
        // 获取文档source
        String json = hit.getSourceAsString();
        // 反序列化
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        // 获取高亮结果
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if ( !CollectionUtils.isEmpty(highlightFields) ) {
            // 根据字段名获取高亮结果
            HighlightField highlightField = highlightFields.get("name");
            if (highlightField != null) {
                // 获取高亮值
                String name = highlightField.getFragments()[0].string();
                // 覆盖非高亮结果
                hotelDoc.setName(name);
            }
        }
        System.out.println("hotelDoc = " + hotelDoc);
    }
}
相关推荐
努力努力再努力wz12 分钟前
【Linux网络系列】:JSON+HTTP,用C++手搓一个web计算器服务器!
java·linux·运维·服务器·c语言·数据结构·c++
魂梦翩跹如雨13 分钟前
死磕排序算法:手撕快速排序的四种姿势(Hoare、挖坑、前后指针 + 非递归)
java·数据结构·算法
sunnyday04262 小时前
Spring Cloud Alibaba Sentinel 流量控制与熔断降级实战指南
spring boot·sentinel·springcloud
带刺的坐椅8 小时前
Solon AI Skills 会是 Agent 的未来吗?
java·agent·langchain4j·solon-ai
jacGJ8 小时前
记录学习--文件读写
java·前端·学习
花间相见8 小时前
【JAVA开发】—— Nginx服务器
java·开发语言·nginx
扶苏-su8 小时前
Java---Properties 类
java·开发语言
cypking8 小时前
四、CRUD操作指南
java
2301_780669869 小时前
文件字节流输出、文件复制、关闭流的方法
java
剑锋所指,所向披靡!10 小时前
C++之类模版
java·jvm·c++