代码编织梦想

SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见。
程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCloud 微服务系列项目开发

elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容。
本项目数据库使用的是 MySql ,查询数据使用的是 ElasticSearch

在这里插入图片描述
本文章接 SpringBoot ElasticSearch 【SpringBoot系列16】

ES 中的数据查询基本步骤:

  • 第一步,创建SearchRequest对象,指定索引库名
  • 第二步,利用request.source()构建DSL,DSL中可以包含查询、分页、排序、高亮等
  • 第三步,利用client.search()发送请求,得到响应
  • 第四步 解析数据
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class ESDocumentTests {

    @Resource
    RestHighLevelClient restHighLevelClient;
    @Test
    void testMatchAll() throws IOException {
        // 1.准备Request
        SearchRequest request = new SearchRequest("order");
        // 2.准备DSL
        request.source()
                .query(QueryBuilders.matchAllQuery());
        // 3.发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        // 4.解析响应
        handleResponse(response);
    }

    private void handleResponse(SearchResponse response) {
        // 4.解析响应
        SearchHits searchHits = response.getHits();
        // 4.1.获取总条数
        long total = searchHits.getTotalHits().value;
        log.info("共搜索到" + total + "条数据");
        // 4.2.文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3.遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            Order order = JSON.parseObject(json, Order.class);
            log.info("查询到数据 {}",order);
        }
    }
}

1 精确查询

上述查询中,QueryBuilders.matchAllQuery() 就是查询条件,在这里没有设置任何筛选条件,所以默认返回前10条数据。

     request.source()
             .query(QueryBuilders.matchAllQuery());

如果要实现精确查询,需要构建查询条件:

 @Test
 public void testBool() throws IOException {
     // 1.准备Request
     SearchRequest request = new SearchRequest("order");
     // 2.准备DSL
     // 2.1.准备BooleanQuery
     BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
     // 2.2.添加term
     boolQuery.must(QueryBuilders.termQuery("goodsName", "手机"));
     // 2.3.添加range
     boolQuery.filter(QueryBuilders.rangeQuery("goodsPrice").lte(250));
     //排序 
     request.source().query(boolQuery);
     // 3.发送请求
     SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
     // 4.解析响应
     handleResponse(response);

 }

核心就是这里的条件

  • term:词条精确匹配
  • range:范围查询
     // 2.2.添加term
     boolQuery.must(QueryBuilders.termQuery("goodsName", "手机"));
     // 2.3.添加range
     boolQuery.filter(QueryBuilders.rangeQuery("goodsPrice").lte(250));

2 查询结果排序与分页

在这里插入图片描述
elasticsearch 在集群模式下,查询TOP1000的数据,例如我集群有5个节点,就必须先查询出每个节点的TOP1000,汇总结果后,重新排名,重新截取TOP1000。
在这里插入图片描述
当查询分页深度较大时,汇总数据过多,对内存和CPU会产生非常大的压力,因此elasticsearch会禁止from+ size 超过10000的请求。

    @Test
    public void testPageAndSort() throws IOException {
        // 页码,每页大小
        int page = 1, size = 5;

        // 1.准备Request
        SearchRequest request = new SearchRequest("order");
        // 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((page - 1) * size).size(5);
        // 3.发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);

    }

核心代码就是

  • sort 排序
  • from 分页
  // 2.2.排序 sort
  request.source().sort("price", SortOrder.ASC);
  // 2.3.分页 from、size
  request.source().from((page - 1) * size).size(5);

3 本项目实现的 订单分页查询

@Api(tags = "订单模块")
@RestController()
@RequestMapping("/orders")
@Slf4j
public class OrderController {
    @Autowired
    private OrderService orderService;
  
    /**
     * 查询用户所有的订单
     */
    @PostMapping("/list")
    public PageResult listFromList(@RequestHeader Long userId,
                                   @RequestBody RequestParams params) {
        PageResult pageResult = orderService.listFromList(userId,params);
        return pageResult;
    }

}

PageResult 是分页信息类

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PageResult {
    /**
     * 当前页码
     */
    private int pageNum;
    /**
     * 每页数量
     */
    private int pageSize;
    /**
     * 记录总数
     */
    private long totalSize;
    /**
     * 页码总数
     */
    private int totalPages;
    /**
     * 数据模型
     */
    private List<?> content;

    public PageResult(long total, List<Order> orderList) {
        this.content = orderList;
        this.totalSize = total;
    }
}

RequestParams 是查询条件 ,包括了分页信息以及订单的状态

@Data
@AllArgsConstructor
public class RequestParams implements Serializable {
    Integer page;
    Integer pageSize;
    Integer statues;
}

最后就是实现订单的分页查询

   @Resource
   RestHighLevelClient restHighLevelClient;
   /**
    * 分页查询用户的订单
    *
    * @param userId
    * @param params
    * @return
    */
   @Override
   public PageResult listFromList(Long userId, RequestParams params) {
       try {
           // 1.准备Request
           SearchRequest request = new SearchRequest("order");
           // 2.准备DSL
           // 1.构建BooleanQuery
           BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

           //查询对应用户的
           boolQuery.must(QueryBuilders.matchQuery("userId", userId));
           //订单状态
           if (params.getStatues() != null && params.getStatues()>=0) {
               boolQuery.filter(QueryBuilders.termQuery("status", params.getStatues()));
           }

           // 分页
           int page = params.getPage();
           int size = params.getPageSize();
           request.source().from((page - 1) * size).size(size);

           // 3.发送请求
           SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
           // 4.解析响应
           return handleResponse(response);
       } catch (IOException e) {
           throw new RuntimeException(e);
       }

   }

   // 结果解析
   private PageResult handleResponse(SearchResponse response) {
       // 4.解析响应
       SearchHits searchHits = response.getHits();
       // 4.1.获取总条数
       long total = searchHits.getTotalHits().value;
       // 4.2.文档数组
       SearchHit[] hits = searchHits.getHits();
       // 4.3.遍历
       List<Order> hotels = new ArrayList<>();
       for (SearchHit hit : hits) {
           // 获取文档source
           String json = hit.getSourceAsString();
           // 反序列化
           Order hotelDoc = JSON.parseObject(json, Order.class);
           // 放入集合
           hotels.add(hotelDoc);
       }
       // 4.4.封装返回
       return new PageResult(total, hotels);
   }

在这里插入图片描述

4 订单的其他操作

ES 中查询订单详情

    @Override
    public Order getOrderDetailFromEs(Long orderId) {
        // 创建获取请求对象
        GetRequest getRequest = new GetRequest("order", "83");
        try {
            GetResponse response = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
            if(response.isExists()){
                log.info("查询到详情 {}",response.getSourceAsString());
                Order hotelDoc = JSON.parseObject(response.getSourceAsString(), Order.class);
                return hotelDoc;
            }else{
                log.error("未消查询到详情");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

ES 中修改订单状态

    /**
     * 更新ES中订单的状态
     * @param statues
     */
    public void updateOrderStatues(Long orderId,Integer statues) {

        // 设置商品更新信息
        Order goods = new Order();
        goods.setStatus(statues);


        // 将对象转为json
        String data = JSON.toJSONString(goods);
        // 创建索引请求对象
        UpdateRequest updateRequest = new UpdateRequest("order", orderId.toString());
        // 设置更新文档内容
        updateRequest.doc(data, XContentType.JSON);
        // 执行更新文档
        UpdateResponse response = null;
        try {
            response = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("更新状态:{}", response.status());
    }

ES 中新增一条订单数据

    /**
     * 下单成功的时候 把数据保存到ES中
     * @param order
     */
    private void saveOrderToEs(Order order){
        // 将对象转为json
        String data = JSON.toJSONString(order);
        // 创建索引请求对象
        // 参数一 索引库名  参数二文档名称
        IndexRequest indexRequest = new IndexRequest("order").id(order.getId() + "");
        // 准备JSON文档
        indexRequest.source(data, XContentType.JSON);
        // 执行增加文档
        IndexResponse response = null;
        try {
            response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
            log.info("创建状态:{}", response.status());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

项目源码在这里 :https://gitee.com/android.long/spring-boot-study/tree/master/biglead-api-12-es
有兴趣可以关注一下公众号:biglead


  1. 创建SpringBoot基础项目
  2. SpringBoot项目集成mybatis
  3. SpringBoot 集成 Druid 数据源【SpringBoot系列3】
  4. SpringBoot MyBatis 实现分页查询数据【SpringBoot系列4】
  5. SpringBoot MyBatis-Plus 集成 【SpringBoot系列5】
  6. SpringBoot mybatis-plus-generator 代码生成器 【SpringBoot系列6】
  7. SpringBoot MyBatis-Plus 分页查询 【SpringBoot系列7】
  8. SpringBoot 集成Redis缓存 以及实现基本的数据缓存【SpringBoot系列8】
  9. SpringBoot 整合 Spring Security 实现安全认证【SpringBoot系列9】
  10. SpringBoot Security认证 Redis缓存用户信息【SpringBoot系列10】
  11. SpringBoot 整合 RabbitMQ 消息队列【SpringBoot系列11】
  12. SpringBoot 结合RabbitMQ与Redis实现商品的并发下单【SpringBoot系列12】
  13. SpringBoot 雪花算法生成商品订单号【SpringBoot系列13】
  14. SpringBoot RabbitMQ 延时队列取消订单【SpringBoot系列14】
  15. SpringBoot RabbitMQ 商品秒杀【SpringBoot系列15】
  16. SpringBoot ElasticSearch 【SpringBoot系列16】
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zl18603543572/article/details/129629817

系列课程 ElasticSearch 之第 8 篇 —— SpringBoot 整合 ElasticSearch 做查询(分页查询)-爱代码爱编程

  本篇博客基于前面第4篇的基础上改造的:https://blog.csdn.net/BiandanLoveyou/article/details/115773729 可以下载前面的代码:https://pan.baidu.com/s/1GnLrGGrP7nhw2Xovq3MtxQ   提取码:mhbi 这里我们需要修改一下 pom.xml 文件

SpringBoot 集成ElasticSearch(二)分页查询-爱代码爱编程

SpringBoot 集成ElasticSearch 之分页查询        SpringBoot 集成ElasticSearch 的代码,我在上一篇博客中已经写过,这边就不重复了。主要记录下service层实现类中分页查询的方法        实体类、配置信息以及新增、更新的代码在上一篇博客中,地址: SpringBoot 集成Elastic

Springboot整合Elasticsearch7,分页高亮查询-爱代码爱编程

Springboot项目引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch<

SpringBoot整合之ElasticSearch条件查询+分页-爱代码爱编程

入门请看es从入门到放弃教学 首先说明我的返回值是一个 PageUtils,因为要做分页 /** * 列表 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params,@RequestBody

springboot整合elasticsearch-crud+分页查询_叫我三胖哥哥的博客-爱代码爱编程

文章目录 1. 环境配置2. 代码编写2.1 Dao层2.2 Service层2.2 Controller层3. 测试结果 ES-docker安装参考这篇: Centos7使用Docker部署Elasticsearch服务+IK分词器及Head插件安装 ES-windows安装参考这篇: windows10安装ElasticSearch与Hea

springboot+elasticsearch 实现模糊查询,批量crud,排序,分页,高亮-爱代码爱编程

点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏  原创 | Java 2021 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件

springboot+elasticsearch 实现模糊查询,批量crud,排序,分页,高亮!-爱代码爱编程

         一、导入elasticsearch依赖 在pom.xml里加入如下依赖 <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-data-e

第四章:springboot整合elasticsearch实现模糊查询,批量crud,排序,分页,高亮-爱代码爱编程

上一章:《第三章:ElasticSearch相关概念》 文章目录 4.1 导入elasticsearch依赖4.2 创建高级客户端4.3 基本用法1.创建、判断存在、删除索引2.对文档的CRUD3.批量新增文档

springboot整合elasticsearch实现模糊查询,排序,分页,高亮-爱代码爱编程

目录 前言 1.框架集成-SpringData-整体介绍 1.1Spring Data Elasticsearch 介绍 2.框架集成Spring Data Elasticsearch 2.1版本说明 2.2.idea创建一个springboot项目 2.3.导入依懒 2.3.增加配置文件 2.4Spring Boot 主程序。 2