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);
    }
}
相关推荐
德思特42 分钟前
从 Dify 配置页理解 RAG 的重要参数
java·人工智能·llm·dify·rag
YOU OU1 小时前
Spring IoC&DI
java·数据库·spring
один but you1 小时前
从可变参数到 emplace:现代 C++ 性能优化的核心组合
java·开发语言
是码龙不是码农2 小时前
ThreadPoolExecutor 7 个核心参数详解
java·线程池·threadpool
这是程序猿2 小时前
Spring Boot自动配置详解
java·大数据·前端
MY_TEUCK2 小时前
【Java 后端 | Nacos 注册中心】微服务治理原理、选型与注册发现实战
java·开发语言·微服务
小江的记录本3 小时前
【Java基础】Java 8-21新特性:JDK21 LTS:虚拟线程、模式匹配switch、结构化并发、序列集合(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
liu_sir_3 小时前
升级谷歌webview
大数据·elasticsearch·搜索引擎
二宝哥4 小时前
离线安装maven
java·数据库·maven
日月云棠4 小时前
6 高级配置:Spring Boot整合、泛化调用与配置指南
java·后端