SpringBoot 整合 Elasticsearch深度分页查询
es 查询共有4种查询类型
QUERY_AND_FETCH:
主节点将查询请求分发到所有的分片中,各个分片按照自己的查询规则即词频文档频率进行打分排序,然后将结果返回给主节点,主节点对所有数据进行汇总排序然后再返回给客户端,此种方式只需要和es交互一次。
这种查询方式存在数据量和排序问题,主节点会汇总所有分片返回的数据这样数据量会比较大,二是各个分片上的规则可能不一致。
QUERY_THEN_FETCH:
主节点将请求分发给所有分片,各个分片打分排序后将数据的id和分值返回给主节点,主节点收到后进行汇总排序再根据排序后的id到对应的节点读取对应的数据再返回给客户端,此种方式需要和es交互两次。
这种方式解决了数据量问题但是排序问题依然存在而且是es的默认查询方式
DEF_QUERY_AND_FETCH 和 DFS_QUERY_THEN_FETCH:
将各个分片的规则统一起来进行打分。解决了排序问题但是DFS_QUERY_AND_FETCH仍然存在数据量问题,DFS_QUERY_THEN_FETCH两种噢乖你问题都解决但是效率是最差的。
Maven依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
yml配置:
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: 127.0.0.1:9300
测试代码:
/**
* @author 宫新程
* @since 2018/10/24 12:29
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class GoodsItemLaunchEsTest { // 查询条件
private static final String ES_SEARCH_ITEM_NAME = "itemName";
private static final String ES_SEARCH_ITEM_MODEL = "itemModel";
private static final String ES_SEARCH_PRODUCT_CODE = "productCode";
private static final String ES_SEARCH_OPER_FLAG = "oper_flag"; @Resource private ElasticsearchTemplate elasticsearchTemplate;
@Resource private EsManager esManager; /** ES创建基础表 */
@Test
public void createIndex() {
elasticsearchTemplate.createIndex(EsGoodsItemLaunchDto.class);
elasticsearchTemplate.putMapping(EsGoodsItemLaunchDto.class);
} /** ES删除表 */
@Test
public void deleteIndex() {
this.elasticsearchTemplate.deleteIndex(EsGoodsItemLaunchDto.class);
} /** 插入测试数据 */
@Test
public void insertData() { List<IndexQuery> queryList = new ArrayList<>(); for (int i = 0; i < 10000; i++) {
EsGoodsItemLaunchDto dto = new EsGoodsItemLaunchDto();
dto.setId(i);
dto.setItemId(i);
dto.setItemSkuId(i);
dto.setItemName(i % 2 == 0 ? "洗衣机" + i : "空调" + i);
dto.setCustomerSellerCode("CustomerSellerCode" + i);
dto.setCustomerName("CustomerName" + i);
dto.setMemberSellerCode("MemberSellerCode" + i);
dto.setMemberName("MemberName" + i);
dto.setProductCode("ProductCode" + i);
dto.setItemModel("ItemModel" + i);
dto.setProductGroupName("ProductGroupName" + i);
dto.setProductGroupCode("ProductGroupCode" + i);
dto.setBrandId(i * 2);
dto.setBrandName("BrandName" + i);
dto.setGmCode(((int) Math.random() * 10000) + "");
dto.setUpdateTime(new Date());
dto.setMemberId(i * 5);
dto.setCustomerId(i * 6); IndexQuery indexQuery =
new IndexQueryBuilder()
.withId(String.valueOf(dto.getId()))
.withObject(dto)
.withIndexName(esManager.index4r(EsGoodsItemLaunchDto.class))
.build(); queryList.add(indexQuery); if (queryList.size() == 1000) {
this.elasticsearchTemplate.bulkIndex(queryList);
queryList.clear();
}
} // 必须加if判断否则报异常:
// org.elasticsearch.action.ActionRequestValidationException:
// Validation Failed: 1:no requests added;
if (queryList.size() > 0) {
// 保存剩余数据 (没被1000整除)
elasticsearchTemplate.bulkIndex(queryList);
}
} @Test
public void search() {
int pageNum = 2;
int pageSize = 5; BoolQueryBuilder filter = QueryBuilders.boolQuery();
// 注意一定要小写处理 toLowerCase()
String codeOrName = "ProductCode100".toLowerCase();
BoolQueryBuilder boolQueryLike = QueryBuilders.boolQuery();
// 分词查询 商品名称
MultiMatchQueryBuilder queryBuilder =
QueryBuilders.multiMatchQuery(codeOrName, ES_SEARCH_ITEM_NAME);
// 商品型号
QueryBuilder itemModel =
QueryBuilders.wildcardQuery(ES_SEARCH_ITEM_MODEL, "*" + codeOrName + "*");
// 产品编码
QueryBuilder productCode =
QueryBuilders.wildcardQuery(ES_SEARCH_PRODUCT_CODE, "*" + codeOrName + "*");
boolQueryLike.should(queryBuilder);
boolQueryLike.should(itemModel);
boolQueryLike.should(productCode);
filter.must(boolQueryLike); // 判断ES表的 oper_flag 不等于 D
filter.mustNot(QueryBuilders.termQuery(ES_SEARCH_OPER_FLAG, "D")); SearchQuery searchQuery = new NativeSearchQuery(filter);
searchQuery.addIndices(esManager.index4r(EsGoodsItemLaunchDto.class));
Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
searchQuery.setPageable(pageable); // 深度查询分页
Page<EsGoodsItemLaunchDto> result =
this.elasticsearchTemplate.startScroll(5000, searchQuery, EsGoodsItemLaunchDto.class); for (int i = 0; i < pageNum - 1; i++) {
elasticsearchTemplate.continueScroll(
((ScrolledPage) result).getScrollId(), 5000, EsGoodsItemLaunchDto.class);
} log.info("=====================================");
result
.getContent()
.forEach(
(dto) -> {
log.info("ItemName:{}", dto.getItemName());
});
log.info("总记录数:{}", result.getTotalElements());
log.info("当前页码数:{}", pageNum);
log.info("每页显示条数:{}", pageSize);
log.info("=====================================");
}
}
/* 输出结果:
<============================>
<ItemName:空调1001>
<ItemName:洗衣机1004>
<ItemName:洗衣机1006>
<ItemName:空调1007>
<ItemName:洗衣机1008>
<总记录数:11>
<当前页码数:2>
<每页显示条数:5>
<============================>
*/
SpringBoot 整合 Elasticsearch深度分页查询的更多相关文章
- SpringBoot整合Mybatis关于分页查询的方法
		
最近公司在用到SpringBoot整合Mybatis时当web端页面数据增多时需要使用分页查询以方便来展示数据.本人对分页查询进行了一些步骤的总结,希望能够帮助到有需要的博友.如有更好的方式,也希望评 ...
 - SpringBoot整合ElasticSearch实现多版本的兼容
		
前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...
 - ElasticSearch(2)---SpringBoot整合ElasticSearch
		
SpringBoot整合ElasticSearch 一.基于spring-boot-starter-data-elasticsearch整合 开发环境:springboot版本:2.0.1,elast ...
 - elasticserach数据库深度分页查询的原理
		
深度分页存在的问题 https://segmentfault.com/a/1190000019004316?utm_source=tag-newest 在实际应用中,分页是必不可少的,例如,前端页面展 ...
 - 😊SpringBoot 整合 Elasticsearch (超详细).md
		
SpringBoot 整合 Elasticsearch (超详细) 注意: 1.环境搭建 安装es Elasticsearch 6.4.3 下载链接 为了方便,环境使用Windows 配置 解压后配置 ...
 - springboot整合elasticsearch入门例子
		
springboot整合elasticsearch入门例子 https://blog.csdn.net/tianyaleixiaowu/article/details/72833940 Elastic ...
 - SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)
		
准备工作 环境准备 JAVA版本 java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121 ...
 - Springboot整合Elasticsearch报错availableProcessors is already set to [4], rejecting [4]
		
Springboot整合Elasticsearch报错 今天使用SpringBoot整合Elasticsearch时候,相关的配置完成后,启动项目就报错了. nested exception is j ...
 - Springboot整合elasticsearch以及接口开发
		
Springboot整合elasticsearch以及接口开发 搭建elasticsearch集群 搭建过程略(我这里用的是elasticsearch5.5.2版本) 写入测试数据 新建索引book( ...
 
随机推荐
- JQuery 数组按指定长度分组
			
JQuery方法 // 将data每3个一组进行分组 var data = ['法国','澳大利亚','智利','新西兰','西班牙','加拿大','阿根廷','美国','0','国产','波多黎各' ...
 - Docker系列(四):容器之间的网络通信
			
首先我们需要知道:两个容器要能通信,必须要有属于同一个网络的网卡. 先来看下正常情况下我们的容器默认是否是能通信的,这里运行两个测试容器: docker run -it --name=bbox1 bu ...
 - vue——动态路由以及地址传参
			
动态路由: 当我们很多个页面或者组件都要被很多次重复利用的时候,我们的路由都指向同一个组件,这时候从不同组件进入一个”共用”的组件,并且还要传参数,渲染不同的数据 这就要用到动态路由跟路由传参了! 1 ...
 - zui框架配置日期控件只显示年月
			
zui框架配置日期控件datetimepicker只显示年月 <!DOCTYPE html> <head> <script src="~/Scripts/jqu ...
 - flask+阿里云短信服务实现注册发送手机验证码
			
效果图: 该效果主要讲解实现通过调用阿里云的SDK实现发送注册验证码短信(阿里云短信付费使用) 购买阿里云短信服务 购买链接:https://www.aliyun.com/product/sms 1. ...
 - 手动模拟JDK动态代理
			
为哪些方法代理? 实现自己动态代理,首先需要关注的点就是,代理对象需要为哪些方法代理? 原生JDK的动态代理的实现是往上抽象出一层接口,让目标对象和代理对象都实现这个接口,怎么把接口的信息告诉jdk原 ...
 - ActiveMQ学习总结------入门篇01
			
注:*这篇博文文章主要介绍ActiveMQ是什么原理性的内容和如何安装和简易操作 一. ActiveMQ 简介 1 ActiveMQ是什么呢?看起来好碉堡的东西哇! ActiveMQ 是 Apach ...
 - Windows和Mac系统下安装Docker
			
在windows和mac系统中使用Docker Desktop安装Docker对系统的要求是很高的. 对于 Windows 系统来说,安装 Docker for Windows 需要符合以下条件: 必 ...
 - 每个新手程序员都必须知道的Python技巧
			
当下,Python 比以往的任何时候都更加流行,人们每天都在实践着 Python 是多么的强大且易用. 我从事 Python 编程已经有几年时间了,但是最近6个月才是全职的.下面列举的这些事情,是我最 ...
 - IoC 之加载 Bean:总结
			
上文中我们将bean已经加载到了IOC容器中,接下来我们将把IOC加载Bean出来进行代码解析 备注:(有些解释是参考别个博客的相关解释 )一起探讨请加我QQ:1051980588 bean 的初始化 ...