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 CSS
JQuery CSS 方法说明 css( name ) 访问第一个匹配元素的样式属性. css( properties ) 把一个"名/值对"对象设置为所有匹配元素的样式属性. $ ...
- CMD的最佳“代替品”
让CMD成为历史 Windows用户大多都使用过"cmd",cmd被称为"阉割版"的DOS系统~ 很多用户除此之外,还喜欢Linux命令行~但是CMD的命令和L ...
- 记录使用echarts的graph类型绘制流程图全过程(一)-x,y位置的计算
先说下本次案例业务需求,输入2个节点,获取数据后绘制出2个节点间的路径,之前使用的是网状图,但是网状图的效果不佳,需要转换成流程图的模式: 那么如何在不修改数据的情况下,实现类似效果尼? 看了下ech ...
- linux下搭建nginx+mysql+apache
对于开发人员来说,进行Web开发时可以用Apache进行网站测试,然而当一个Web程序进行发布时,Apache中并发性能差就显得很突出,这时配置一台Nginx服务器显得尤为重要. 以下是配置Nginx ...
- 深圳市网络安全中心发出通告,TeamViewer已被APT41黑客攻破
上期我们讲了东南亚赌局为什么都是福建老板了,这次来介绍下黑客组织APT41 ,这个组织在 HT界 比较出名,很早之前是匿名在地下交易所的,而在近年频繁出现在大众视野中,这不,刚刚又把我们常用的远程工具 ...
- java第1天:简介,入门程序,变量,常量
1 java语言简介 美国的SUN公司开发的静态面向对象的编程语言,后来被甲骨文公司收购,现在也是全球范围内最受欢迎的编程语言. *** 2 计算机进制的相互转换 进制 英文代号 2进制 bin 8进 ...
- nginx的负载均衡实战
前言 nginx是一个高性能的HTTP和反向代理的服务器.它有三个最基本的功能,一是当做web服务器.二是作为反向代理服务器.三是提供负载均衡(在反向代理基础上),由于它占有内存小,并发能力强,所以在 ...
- Python3 pygal 与 pygal_maps_world 绘制世界地图
直接代码: import pygalfrom pygal_maps_world.i18n import COUNTRIES def word_country_map(): ""&q ...
- Zookeeper未授权访问测试
前言 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提 ...
- formidable处理提交的表单或文件的简单介绍
一般来说,客户端向服务端提交数据有GET和POST这两种方式,在之前的文章node.js当中的http模块与url模块的简单介绍当中我们可以知道通过req.url与url模块的配合处理可以快速得到客户 ...