​SpringBoot 整合 Elasticsearch深度分页查询​

我就是我 2022-09-15 00:56 478阅读 0赞

SpringBoot 整合 Elasticsearch深度分页查询

es 查询共有4种查询类型

QUERY_AND_FETCH:

  主节点将查询请求分发到所有的分片中,各个分片按照自己的查询规则即词频文档频率进行打分排序,然后将结果返回给主节点,主节点对所有数据进行汇总排序然后再返回给客户端,此种方式只需要和es交互一次。

  1. 这种查询方式存在数据量和排序问题,主节点会汇总所有分片返回的数据这样数据量会比较大,二是各个分片上的规则可能不一致。

QUERY_THEN_FETCH:

主节点将请求分发给所有分片,各个分片打分排序后将数据的id和分值返回给主节点,主节点收到后进行汇总排序再根据排序后的id到对应的节点读取对应的数据再返回给客户端,此种方式需要和es交互两次。

  1. 这种方式解决了数据量问题但是排序问题依然存在而且是es的默认查询方式

DEF_QUERY_AND_FETCH 和 DFS_QUERY_THEN_FETCH:

  将各个分片的规则统一起来进行打分。解决了排序问题但是DFS_QUERY_AND_FETCH仍然存在数据量问题,DFS_QUERY_THEN_FETCH两种噢乖你问题都解决但是效率是最差的。

Maven依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4.     <version>2.0.5.RELEASE</version> 
  5. </dependency>

yml配置:

  1. spring:
  2. data:
  3. elasticsearch:
  4. cluster-name: elasticsearch
  5. cluster-nodes: 127.0.0.1:9300

测试代码:

复制代码

  1. 1 /**
  2. 2 * @author 宫新程
  3. 3 * @since 2018/10/24 12:29
  4. 4 */
  5. 5 @RunWith(SpringRunner.class)
  6. 6 @SpringBootTest
  7. 7 @Slf4j
  8. 8 public class GoodsItemLaunchEsTest {
  9. 9
  10. 10 // 查询条件
  11. 11 private static final String ES_SEARCH_ITEM_NAME = "itemName";
  12. 12 private static final String ES_SEARCH_ITEM_MODEL = "itemModel";
  13. 13 private static final String ES_SEARCH_PRODUCT_CODE = "productCode";
  14. 14 private static final String ES_SEARCH_OPER_FLAG = "oper_flag";
  15. 15
  16. 16 @Resource private ElasticsearchTemplate elasticsearchTemplate;
  17. 17 @Resource private EsManager esManager;
  18. 18
  19. 19 /** ES创建基础表 */
  20. 20 @Test
  21. 21 public void createIndex() {
  22. 22 elasticsearchTemplate.createIndex(EsGoodsItemLaunchDto.class);
  23. 23 elasticsearchTemplate.putMapping(EsGoodsItemLaunchDto.class);
  24. 24 }
  25. 25
  26. 26 /** ES删除表 */
  27. 27 @Test
  28. 28 public void deleteIndex() {
  29. 29 this.elasticsearchTemplate.deleteIndex(EsGoodsItemLaunchDto.class);
  30. 30 }
  31. 31
  32. 32 /** 插入测试数据 */
  33. 33 @Test
  34. 34 public void insertData() {
  35. 35
  36. 36 List<IndexQuery> queryList = new ArrayList<>();
  37. 37
  38. 38 for (int i = 0; i < 10000; i++) {
  39. 39 EsGoodsItemLaunchDto dto = new EsGoodsItemLaunchDto();
  40. 40 dto.setId(i);
  41. 41 dto.setItemId(i);
  42. 42 dto.setItemSkuId(i);
  43. 43 dto.setItemName(i % 2 == 0 ? "洗衣机" + i : "空调" + i);
  44. 44 dto.setCustomerSellerCode("CustomerSellerCode" + i);
  45. 45 dto.setCustomerName("CustomerName" + i);
  46. 46 dto.setMemberSellerCode("MemberSellerCode" + i);
  47. 47 dto.setMemberName("MemberName" + i);
  48. 48 dto.setProductCode("ProductCode" + i);
  49. 49 dto.setItemModel("ItemModel" + i);
  50. 50 dto.setProductGroupName("ProductGroupName" + i);
  51. 51 dto.setProductGroupCode("ProductGroupCode" + i);
  52. 52 dto.setBrandId(i * 2);
  53. 53 dto.setBrandName("BrandName" + i);
  54. 54 dto.setGmCode(((int) Math.random() * 10000) + "");
  55. 55 dto.setUpdateTime(new Date());
  56. 56 dto.setMemberId(i * 5);
  57. 57 dto.setCustomerId(i * 6);
  58. 58
  59. 59 IndexQuery indexQuery =
  60. 60 new IndexQueryBuilder()
  61. 61 .withId(String.valueOf(dto.getId()))
  62. 62 .withObject(dto)
  63. 63 .withIndexName(esManager.index4r(EsGoodsItemLaunchDto.class))
  64. 64 .build();
  65. 65
  66. 66 queryList.add(indexQuery);
  67. 67
  68. 68 if (queryList.size() == 1000) {
  69. 69 this.elasticsearchTemplate.bulkIndex(queryList);
  70. 70 queryList.clear();
  71. 71 }
  72. 72 }
  73. 73
  74. 74 // 必须加if判断否则报异常:
  75. 75 // org.elasticsearch.action.ActionRequestValidationException:
  76. 76 // Validation Failed: 1:no requests added;
  77. 77 if (queryList.size() > 0) {
  78. 78 // 保存剩余数据 (没被1000整除)
  79. 79 elasticsearchTemplate.bulkIndex(queryList);
  80. 80 }
  81. 81 }
  82. 82
  83. 83 @Test
  84. 84 public void search() {
  85. 85 int pageNum = 2;
  86. 86 int pageSize = 5;
  87. 87
  88. 88 BoolQueryBuilder filter = QueryBuilders.boolQuery();
  89. 89 // 注意一定要小写处理 toLowerCase()
  90. 90 String codeOrName = "ProductCode100".toLowerCase();
  91. 91 BoolQueryBuilder boolQueryLike = QueryBuilders.boolQuery();
  92. 92 // 分词查询 商品名称
  93. 93 MultiMatchQueryBuilder queryBuilder =
  94. 94 QueryBuilders.multiMatchQuery(codeOrName, ES_SEARCH_ITEM_NAME);
  95. 95 // 商品型号
  96. 96 QueryBuilder itemModel =
  97. 97 QueryBuilders.wildcardQuery(ES_SEARCH_ITEM_MODEL, "*" + codeOrName + "*");
  98. 98 // 产品编码
  99. 99 QueryBuilder productCode =
  100. 100 QueryBuilders.wildcardQuery(ES_SEARCH_PRODUCT_CODE, "*" + codeOrName + "*");
  101. 101 boolQueryLike.should(queryBuilder);
  102. 102 boolQueryLike.should(itemModel);
  103. 103 boolQueryLike.should(productCode);
  104. 104 filter.must(boolQueryLike);
  105. 105
  106. 106 // 判断ES表的 oper_flag 不等于 D
  107. 107 filter.mustNot(QueryBuilders.termQuery(ES_SEARCH_OPER_FLAG, "D"));
  108. 108
  109. 109 SearchQuery searchQuery = new NativeSearchQuery(filter);
  110. 110 searchQuery.addIndices(esManager.index4r(EsGoodsItemLaunchDto.class));
  111. 111 Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
  112. 112 searchQuery.setPageable(pageable);
  113. 113
  114. 114 // 深度查询分页
  115. 115 Page<EsGoodsItemLaunchDto> result =
  116. 116 this.elasticsearchTemplate.startScroll(5000, searchQuery, EsGoodsItemLaunchDto.class);
  117. 117
  118. 118 for (int i = 0; i < pageNum - 1; i++) {
  119. 119 elasticsearchTemplate.continueScroll(
  120. 120 ((ScrolledPage) result).getScrollId(), 5000, EsGoodsItemLaunchDto.class);
  121. 121 }
  122. 122
  123. 123 log.info("=====================================");
  124. 124 result
  125. 125 .getContent()
  126. 126 .forEach(
  127. 127 (dto) -> {
  128. 128 log.info("ItemName:{}", dto.getItemName());
  129. 129 });
  130. 130 log.info("总记录数:{}", result.getTotalElements());
  131. 131 log.info("当前页码数:{}", pageNum);
  132. 132 log.info("每页显示条数:{}", pageSize);
  133. 133 log.info("=====================================");
  134. 134 }
  135. 135 }
  136. 136 /* 输出结果:
  137. 137 <============================>
  138. 138 <ItemName:空调1001>
  139. 139 <ItemName:洗衣机1004>
  140. 140 <ItemName:洗衣机1006>
  141. 141 <ItemName:空调1007>
  142. 142 <ItemName:洗衣机1008>
  143. 143 <总记录数:11>
  144. 144 <当前页码数:2>
  145. 145 <每页显示条数:5>
  146. 146 <============================>
  147. 147 */

发表评论

表情:
评论列表 (有 0 条评论,478人围观)

还没有评论,来说两句吧...

相关阅读