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

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
简介: 上一节讲述了 SpringBoot 实现 elasticsearch 索引操作,这一章节讲述 SpringBoot 实现 elasticsearch 查询操作。1. 环境准备案例用到的索引库结构

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


1. 环境准备

案例用到的索引库结构

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. 查询全部

@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 分词查询

 @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 分词查询

@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 分词查询

@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. 按照价格 范围查询

 @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. 精确查询

@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

@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. 分页

 @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. 高亮查询

 @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. 公共解析

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);
    }
}

相关实践学习
利用Elasticsearch实现地理位置查询
本实验将分别介绍如何使用Elasticsearch7.10版本进行全文检索、多语言检索和地理位置查询三个Elasticsearch基础检索子场景的实现。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
4天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的武汉市公交路线查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的武汉市公交路线查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
4天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的城市公交在线查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的城市公交在线查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
8天前
|
Java 关系型数据库 API
使用Spring Boot和PostgreSQL构建高级查询
使用Spring Boot和PostgreSQL构建高级查询
|
21天前
|
缓存 NoSQL Java
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
62 5
|
22天前
|
JSON 前端开发 Java
Springboot mvc开发之Rest风格及RESTful简化开发案例
Springboot mvc开发之Rest风格及RESTful简化开发案例
24 2
|
22天前
|
SQL Java 数据库连接
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
2万字实操案例之在Springboot框架下基于注解用Mybatis开发实现基础操作MySQL之预编译SQL主键返回增删改查
26 2
|
4天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的企业职工薪资查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的企业职工薪资查询系统的详细设计和实现(源码+lw+部署文档+讲解等)
|
7天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的公共交通查询系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的公共交通查询系统附带文章源码部署视频讲解等
8 0
|
7天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的城市公交查询系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的城市公交查询系统附带文章源码部署视频讲解等
10 0
|
7天前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的武汉市公交路线查询系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的武汉市公交路线查询系统附带文章源码部署视频讲解等
10 0