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( ...
随机推荐
- 两台CentOS6.5 在不同机器上互联
准备工作 1.安装vmware及虚拟机centos6.5: 2.将安装好的centos6.5复制一份,在另一台机器上拷贝. 要进行不同机器上虚拟机的互相通信,需要用桥接模式进行互联.如下图,对vmwa ...
- bullet物理引擎与OpenGL结合 导入3D模型进行碰撞检测 以及画三角网格的坑
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11681069.html 一.初始化世界以及模型 /// 冲突配置包含内存的默认设置,冲突设置. ...
- Executor线程池原理详解
线程池 线程池的目的就是减少多线程创建的开销,减少资源的消耗,让系统更加的稳定.在web开发中,服务器会为了一个请求分配一个线程来处理,如果每次请求都创建一个线程,请求结束就销毁这个线程.那么在高并发 ...
- python编程基础之二十四
函数: def 函数名([参数1],[参数2],[参数3], ... ,[参数n]): 函数体代码 函数名命名规则:同标识符命名相同,但是多了一点,不要和系统函数重名,其实所有命名都是一样只要符合标识 ...
- .NET GC垃圾回收器
GC垃圾回收器简介 全名: Garbage Collector 原理: 以应用程序的根(root)为基础,遍历应用程序堆(heap)上动态分配的所有对象,通过识别它们是否被引用来确定哪些对象是已经死亡 ...
- Docker 配置国内镜像
前言 当我们使用Docker pull 拉取镜像时,有时候因网络问题,导致获取镜像报错,如下 :Error response from daemon:Get https://registry-1.co ...
- java架构之路-(Redis专题)Redis的主从、哨兵和集群
我们使用的redis,单机的绝对做不到高可用的,万一单机的redis宕机了,就没有备用的了,我们可以采用集群的方式来保证我们的高可用操作. 主从架构 大致就是这样的,一个主节点,两个从节点(一般两个就 ...
- thinkphp5框架之请求
又看到请求这一部分,个人认为这部分是算重要的一部分 单独记一篇笔记. 0x01 request请求对象 如果要获取当前的请求信息,可以使用\think\Request类,完全开发手册中也有提到,继承系 ...
- 理解JavaScript中的堆和栈
这里先说两个概念:1.堆(heap)2.栈(stack)堆 是堆内存的简称.栈 是栈内存的简称.说到堆栈,我们讲的就是内存的使用和分配了,没有寄存器的事,也没有硬盘的事.各种语言在处理堆栈的原理上都大 ...
- 路由器静态IP的配置及其备份静态路由缺省路由
静态路由时管理员手动配置并维护的路由.静态路由配置简单,被广泛应用于网络中.静态路由还可以实现负载均衡和路由备份.学习掌握好静态路由的配置是很重要的. 如下图, 首先进入路由器的命令视图,(sys) ...