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深度分页查询的更多相关文章

  1. SpringBoot整合Mybatis关于分页查询的方法

    最近公司在用到SpringBoot整合Mybatis时当web端页面数据增多时需要使用分页查询以方便来展示数据.本人对分页查询进行了一些步骤的总结,希望能够帮助到有需要的博友.如有更好的方式,也希望评 ...

  2. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

  3. ElasticSearch(2)---SpringBoot整合ElasticSearch

    SpringBoot整合ElasticSearch 一.基于spring-boot-starter-data-elasticsearch整合 开发环境:springboot版本:2.0.1,elast ...

  4. elasticserach数据库深度分页查询的原理

    深度分页存在的问题 https://segmentfault.com/a/1190000019004316?utm_source=tag-newest 在实际应用中,分页是必不可少的,例如,前端页面展 ...

  5. 😊SpringBoot 整合 Elasticsearch (超详细).md

    SpringBoot 整合 Elasticsearch (超详细) 注意: 1.环境搭建 安装es Elasticsearch 6.4.3 下载链接 为了方便,环境使用Windows 配置 解压后配置 ...

  6. springboot整合elasticsearch入门例子

    springboot整合elasticsearch入门例子 https://blog.csdn.net/tianyaleixiaowu/article/details/72833940 Elastic ...

  7. SpringBoot整合Elasticsearch详细步骤以及代码示例(附源码)

    准备工作 环境准备 JAVA版本 java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121 ...

  8. Springboot整合Elasticsearch报错availableProcessors is already set to [4], rejecting [4]

    Springboot整合Elasticsearch报错 今天使用SpringBoot整合Elasticsearch时候,相关的配置完成后,启动项目就报错了. nested exception is j ...

  9. Springboot整合elasticsearch以及接口开发

    Springboot整合elasticsearch以及接口开发 搭建elasticsearch集群 搭建过程略(我这里用的是elasticsearch5.5.2版本) 写入测试数据 新建索引book( ...

随机推荐

  1. python pytesseract——3步识别验证码的识别入门

    验证码识别是个大工程,但入门开始只要3步.需要用到的库PIL.pytesserac,没有的话pip安装.还有一个是tesseract-ocr 下载地址:https://sourceforge.net/ ...

  2. electron教程(四): 使用electron-builder或electron-packager将项目打包为可执行桌面程序(.exe)

    我的electron教程系列 electron教程(一): electron的安装和项目的创建 electron教程(二): http服务器, ws服务器, 子进程管理 electron教程(三): ...

  3. 52个有效方法(1) - 了解Objective-C语言的起源

    Objective-C语言使用的是"消息结构"而非"函数调用" "消息结构"和"函数调用"之间的区别 "消息结 ...

  4. 浅谈分布式事务与TX-LCN

    最近做项目使用到了分布式事务,下面这篇文章将给大家介绍一下对分布式事务的一些见解,并讲解分布式事务处理框架TX-LCN的执行原理,初学入门,错误之处望各位不吝指正. 什么情况下需要使用分布式事务? 使 ...

  5. File类&递归

    File类1.什么是file类Java中处理操作系统文件的类.2.file思想创建一个File对象,代表了操作系统的具体的一个文件(文件,文件夹)然后通过这个File对象就可以操作该文件:删除该文件, ...

  6. django渲染高阶

    08.16自我总结 django渲染高阶 一.利用母版渲染 1.创建母版文件 如:stamper.html <!DOCTYPE html> <html lang="en&q ...

  7. 使用Xming显示Oracle Linux图形界面

    如果你在尝试各种官方说明文档中的方法之后,xclock仍然无法远程显示. 系统 Win10 - Oracle Linux 7.5 Xming的文档以及网上教程都说的是Xming相关的配置 但是,要显示 ...

  8. windows离线安装sublime插件:ctags

    网络上一堆安装ctags教程,可都是在线安装. 花了点时间摸索出了离线安装教程. 1. 准备好sublime 和 package control sublime我用的版本是text 2. text 3 ...

  9. Hadoop(MapR)分布式安装及自动化脚本配置

    MapR的分布式集群安装过程还是很艰难的,远远没有计划中的简单.本人总结安装配置,由于集群有很多机器,手动每台配置是很累的,编写了一个自动化配置脚本,下面以脚本为主线叙述(脚本并不完善,后续继续完善中 ...

  10. LeetCode初级算法--排序和搜索01:第一个错误的版本

    LeetCode初级算法--排序和搜索01:第一个错误的版本 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.cs ...