QueryDataServiceImpl.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. package com.fdkankan.elasticsearch.service.impl;
  2. import com.alibaba.fastjson.JSON;
  3. import com.fdkankan.elasticsearch.service.QueryDataService;
  4. import lombok.extern.log4j.Log4j2;
  5. import org.apache.commons.lang3.StringUtils;
  6. import org.elasticsearch.action.search.SearchRequest;
  7. import org.elasticsearch.action.search.SearchResponse;
  8. import org.elasticsearch.client.RequestOptions;
  9. import org.elasticsearch.client.RestHighLevelClient;
  10. import org.elasticsearch.common.text.Text;
  11. import org.elasticsearch.common.unit.Fuzziness;
  12. import org.elasticsearch.index.query.BoolQueryBuilder;
  13. import org.elasticsearch.index.query.MatchAllQueryBuilder;
  14. import org.elasticsearch.index.query.MatchQueryBuilder;
  15. import org.elasticsearch.index.query.QueryBuilders;
  16. import org.elasticsearch.rest.RestStatus;
  17. import org.elasticsearch.search.SearchHit;
  18. import org.elasticsearch.search.SearchHits;
  19. import org.elasticsearch.search.aggregations.AggregationBuilder;
  20. import org.elasticsearch.search.aggregations.AggregationBuilders;
  21. import org.elasticsearch.search.aggregations.Aggregations;
  22. import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
  23. import org.elasticsearch.search.aggregations.bucket.terms.Terms;
  24. import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
  25. import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
  26. import org.elasticsearch.search.aggregations.metrics.ParsedMax;
  27. import org.elasticsearch.search.aggregations.metrics.ParsedMin;
  28. import org.elasticsearch.search.builder.SearchSourceBuilder;
  29. import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
  30. import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
  31. import org.elasticsearch.search.sort.SortOrder;
  32. import org.springframework.beans.factory.annotation.Autowired;
  33. import org.springframework.stereotype.Service;
  34. import java.io.IOException;
  35. import java.lang.reflect.Method;
  36. import java.util.ArrayList;
  37. import java.util.List;
  38. import java.util.Objects;
  39. /**
  40. * @author yanfengzhang
  41. * @description
  42. * @date 2022/12/8 23:37
  43. */
  44. @Service
  45. @Log4j2
  46. public class QueryDataServiceImpl implements QueryDataService {
  47. @Autowired
  48. private RestHighLevelClient restHighLevelClient;
  49. /**
  50. * 精确查询(termQuery)
  51. *
  52. * @param indexName 索引名
  53. * @param columnName 列名或字段名
  54. * @param value 查询内容
  55. * @param classz 数据结构
  56. * @param <T> 数据结构
  57. * @return 精确查询内容数据
  58. */
  59. @Override
  60. public <T> List<T> termQuery(String indexName, String columnName, Object value, Class<T> classz) {
  61. /* 查询的数据列表 */
  62. List<T> list = new ArrayList<>();
  63. try {
  64. /*构建查询条件(注意:termQuery 支持多种格式查询,如 boolean、int、double、string 等,这里使用的是 string 的查询)*/
  65. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  66. searchSourceBuilder.query(QueryBuilders.termQuery(columnName, value));
  67. /*执行查询es数据*/
  68. queryEsData(indexName, classz, list, searchSourceBuilder);
  69. } catch (IOException e) {
  70. log.error("精确查询数据失败,错误信息:", e);
  71. }
  72. return list;
  73. }
  74. /**
  75. * terms:多个查询内容在一个字段中进行查询
  76. *
  77. * @param indexName 索引名
  78. * @param columnName 列名或字段名
  79. * @param dataArgs 查询内容集合
  80. * @param classz 数据结构
  81. * @param <T> 数据结构
  82. * @return 多个查询内容在一个字段中进行查询对应结果
  83. */
  84. @Override
  85. public <T> List<T> termsQuery(String indexName, String columnName, Object[] dataArgs, Class<T> classz) {
  86. /*查询的数据列表*/
  87. List<T> list = new ArrayList<>();
  88. try {
  89. /* 构建查询条件(注意:termsQuery 支持多种格式查询,如 boolean、int、double、string 等,这里使用的是 string 的查询)*/
  90. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  91. searchSourceBuilder.query(QueryBuilders.termsQuery(columnName, dataArgs));
  92. /*展示100条,默认只展示10条记录*/
  93. searchSourceBuilder.size(100);
  94. /*执行查询es数据*/
  95. queryEsData(indexName, classz, list, searchSourceBuilder);
  96. } catch (IOException e) {
  97. log.error("单字段多内容查询数据失败,错误信息:", e);
  98. }
  99. return list;
  100. }
  101. /**
  102. * 匹配查询符合条件的所有数据,并设置分页
  103. *
  104. * @param indexName 索引名
  105. * @param classz 数据结构
  106. * @param startIndex 起始下标
  107. * @param pageSize 页大小
  108. * @param orderList 设置排序
  109. * @param columnName 列名或字段名
  110. * @param value 列名或字段名指定内容
  111. * @param <T> 数据结构
  112. * @return 符合条件的所有数据
  113. */
  114. @Override
  115. public <T> List<T> matchAllQuery(String indexName, Class<T> classz, int startIndex, int pageSize, List<String> orderList, String columnName, Object value) {
  116. /*查询的数据列表*/
  117. List<T> list = new ArrayList<>();
  118. try {
  119. /*创建查询源构造器*/
  120. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  121. /*构建查询条件*/
  122. if (StringUtils.isNotBlank(columnName) && Objects.nonNull(value)) {
  123. MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(columnName, value);
  124. searchSourceBuilder.query(matchQueryBuilder);
  125. } else {
  126. MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
  127. searchSourceBuilder.query(matchAllQueryBuilder);
  128. }
  129. /*设置分页*/
  130. searchSourceBuilder.from(startIndex);
  131. searchSourceBuilder.size(pageSize);
  132. /*设置排序*/
  133. if (orderList != null) {
  134. for (String order : orderList) {
  135. /*开头代表:倒序*/
  136. boolean flag = order.startsWith("-");
  137. SortOrder sort = flag ? SortOrder.DESC : SortOrder.ASC;
  138. order = flag ? order.substring(1) : order;
  139. searchSourceBuilder.sort(order, sort);
  140. }
  141. }
  142. /*执行查询es数据*/
  143. queryEsData(indexName, classz, list, searchSourceBuilder);
  144. } catch (IOException e) {
  145. log.error("查询所有数据失败,错误信息:", e);
  146. }
  147. return list;
  148. }
  149. /**
  150. * 词语匹配查询
  151. *
  152. * @param indexName 索引名
  153. * @param classz 数据结构
  154. * @param columnName 列名或字段名
  155. * @param value 指定内容
  156. * @param <T> 数据结构
  157. * @return 词语匹配查询结果
  158. */
  159. @Override
  160. public <T> List<T> matchPhraseQuery(String indexName, Class<T> classz, String columnName, Object value) {
  161. /*查询的数据列表*/
  162. List<T> list = new ArrayList<>();
  163. try {
  164. /*构建查询条件*/
  165. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  166. searchSourceBuilder.query(QueryBuilders.matchPhraseQuery(columnName, value));
  167. /*执行查询es数据*/
  168. queryEsData(indexName, classz, list, searchSourceBuilder);
  169. } catch (IOException e) {
  170. log.error("词语匹配查询失败,错误信息:", e);
  171. }
  172. return list;
  173. }
  174. /**
  175. * 内容在多字段中进行查询
  176. *
  177. * @param indexName 索引名
  178. * @param classz 数据结构
  179. * @param fields 列名或字段名集合
  180. * @param text 指定内容
  181. * @param <T> 数据结构
  182. * @return 查询结果
  183. */
  184. @Override
  185. public <T> List<T> matchMultiQuery(String indexName, Class<T> classz, String[] fields, Object text) {
  186. /*查询的数据列表*/
  187. List<T> list = new ArrayList<>();
  188. try {
  189. /*构建查询条件*/
  190. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  191. /*设置查询条件*/
  192. searchSourceBuilder.query(QueryBuilders.multiMatchQuery(text, fields));
  193. /*执行查询es数据*/
  194. queryEsData(indexName, classz, list, searchSourceBuilder);
  195. } catch (IOException e) {
  196. log.error("词语匹配查询失败,错误信息:", e);
  197. }
  198. return list;
  199. }
  200. /**
  201. * 通配符查询(wildcard):会对查询条件进行分词。还可以使用通配符 ?(任意单个字符) 和 * (0个或多个字符)
  202. *
  203. * @param indexName 索引名
  204. * @param classz 数据结构
  205. * @param field 列名或字段名集合
  206. * @param text 指定内容
  207. * @param <T> 数据结构
  208. * @return 查询结果
  209. */
  210. @Override
  211. public <T> List<T> wildcardQuery(String indexName, Class<T> classz, String field, String text) {
  212. /*查询的数据列表*/
  213. List<T> list = new ArrayList<>();
  214. try {
  215. /*构建查询条件*/
  216. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  217. searchSourceBuilder.query(QueryBuilders.wildcardQuery(field, text));
  218. /*执行查询es数据*/
  219. queryEsData(indexName, classz, list, searchSourceBuilder);
  220. } catch (IOException e) {
  221. log.error("通配符查询失败,错误信息:", e);
  222. }
  223. return list;
  224. }
  225. /**
  226. * 模糊查询商品信息
  227. *
  228. * @param indexName 索引名
  229. * @param classz 数据结构
  230. * @param field 列名或字段名集合
  231. * @param text 指定内容
  232. * @param <T> 数据结构
  233. * @return 查询结果
  234. */
  235. @Override
  236. public <T> List<T> fuzzyQuery(String indexName, Class<T> classz, String field, String text) {
  237. /*查询的数据列表*/
  238. List<T> list = new ArrayList<>();
  239. try {
  240. /*构建查询条件*/
  241. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  242. searchSourceBuilder.query(QueryBuilders.fuzzyQuery(field, text).fuzziness(Fuzziness.AUTO));
  243. /*执行查询es数据*/
  244. queryEsData(indexName, classz, list, searchSourceBuilder);
  245. } catch (IOException e) {
  246. log.error("通配符查询失败,错误信息:", e);
  247. }
  248. return list;
  249. }
  250. /**
  251. * boolQuery 查询
  252. * 高亮展示标题搜索字段
  253. * 设置出参返回字段
  254. * 案例:查询从2018-2022年间标题含 三星 的商品信息
  255. *
  256. * @param indexName 索引名
  257. * @param beanClass 数据结构
  258. * @param <T> 数据结构
  259. * @return 查询结果
  260. */
  261. @Override
  262. public <T> List<T> boolQuery(String indexName, Class<T> beanClass) {
  263. /*查询的数据列表*/
  264. List<T> list = new ArrayList<>();
  265. try {
  266. /*创建 Bool 查询构建器*/
  267. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  268. /*构建查询条件*/
  269. /*构建查询源构建器*/
  270. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  271. searchSourceBuilder.query(boolQueryBuilder);
  272. searchSourceBuilder.size(100);
  273. /*甚至返回字段
  274. 如果查询的属性很少,那就使用includes,而excludes设置为空数组
  275. 如果排序的属性很少,那就使用excludes,而includes设置为空数组*/
  276. /*创建查询请求对象,将查询对象配置到其中*/
  277. SearchRequest searchRequest = new SearchRequest(indexName);
  278. searchRequest.source(searchSourceBuilder);
  279. /*执行查询,然后处理响应结果*/
  280. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  281. /*根据状态和数据条数验证是否返回了数据*/
  282. if (RestStatus.OK.equals(searchResponse.status()) && searchResponse.getHits().getTotalHits().value > 0) {
  283. SearchHits hits = searchResponse.getHits();
  284. for (SearchHit hit : hits) {
  285. /* 将 JSON 转换成对象*/
  286. T bean = JSON.parseObject(hit.getSourceAsString(), beanClass);
  287. /*获取高亮的数据*/
  288. HighlightField highlightField = hit.getHighlightFields().get("title");
  289. log.info("高亮名称:{}", highlightField.getFragments()[0].string());
  290. /*替换掉原来的数据*/
  291. Text[] fragments = highlightField.getFragments();
  292. if (fragments != null && fragments.length > 0) {
  293. StringBuilder title = new StringBuilder();
  294. for (Text fragment : fragments) {
  295. title.append(fragment);
  296. }
  297. /* 获取method对象,其中包含方法名称和参数列表*/
  298. Method setTitle = beanClass.getMethod("setTitle", String.class);
  299. if (setTitle != null) {
  300. /*执行method,bean为实例对象,后面是方法参数列表;setTitle没有返回值*/
  301. setTitle.invoke(bean, title.toString());
  302. }
  303. }
  304. list.add(bean);
  305. }
  306. }
  307. } catch (Exception e) {
  308. log.error("布尔查询失败,错误信息:", e);
  309. }
  310. return list;
  311. }
  312. /**
  313. * 聚合查询 : 聚合查询一定是【先查出结果】,然后对【结果使用聚合函数】做处理.
  314. * Metric 指标聚合分析。常用的操作有:avg:求平均、max:最大值、min:最小值、sum:求和等
  315. * 案例:分别获取最贵的商品和获取最便宜的商品
  316. *
  317. * @param indexName 索引名
  318. */
  319. @Override
  320. public void metricQuery(String indexName) {
  321. try {
  322. /* 构建查询条件*/
  323. MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
  324. /*创建查询源构造器*/
  325. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  326. searchSourceBuilder.query(matchAllQueryBuilder);
  327. /*获取最贵的商品*/
  328. AggregationBuilder maxPrice = AggregationBuilders.max("maxPrice").field("price");
  329. searchSourceBuilder.aggregation(maxPrice);
  330. /*获取最便宜的商品*/
  331. AggregationBuilder minPrice = AggregationBuilders.min("minPrice").field("price");
  332. searchSourceBuilder.aggregation(minPrice);
  333. /*创建查询请求对象,将查询对象配置到其中*/
  334. SearchRequest searchRequest = new SearchRequest(indexName);
  335. searchRequest.source(searchSourceBuilder);
  336. /*执行查询,然后处理响应结果*/
  337. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  338. Aggregations aggregations = searchResponse.getAggregations();
  339. ParsedMax max = aggregations.get("maxPrice");
  340. log.info("最贵的价格:" + max.getValue());
  341. ParsedMin min = aggregations.get("minPrice");
  342. log.info("最便宜的价格:" + min.getValue());
  343. } catch (Exception e) {
  344. log.error("指标聚合分析查询失败,错误信息:", e);
  345. }
  346. }
  347. /**
  348. * 聚合查询: 聚合查询一定是【先查出结果】,然后对【结果使用聚合函数】做处理
  349. * Bucket 分桶聚合分析 : 对查询出的数据进行分组group by,再在组上进行游标聚合
  350. * 案例:根据品牌进行聚合查询
  351. *
  352. * @param indexName 索引名
  353. * @param bucketField
  354. * @param bucketFieldAlias
  355. */
  356. @Override
  357. public void bucketQuery(String indexName, String bucketField, String bucketFieldAlias) {
  358. try {
  359. /*构建查询条件*/
  360. MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
  361. /*创建查询源构造器*/
  362. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  363. searchSourceBuilder.query(matchAllQueryBuilder);
  364. /*根据bucketField进行分组查询*/
  365. TermsAggregationBuilder aggBrandName = AggregationBuilders.terms(bucketFieldAlias).field(bucketField);
  366. searchSourceBuilder.aggregation(aggBrandName);
  367. /*创建查询请求对象,将查询对象配置到其中*/
  368. SearchRequest searchRequest = new SearchRequest(indexName);
  369. searchRequest.source(searchSourceBuilder);
  370. /*执行查询,然后处理响应结果*/
  371. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  372. Aggregations aggregations = searchResponse.getAggregations();
  373. /*分组结果数据*/
  374. ParsedStringTerms aggBrandName1 = aggregations.get(bucketFieldAlias);
  375. for (Terms.Bucket bucket : aggBrandName1.getBuckets()) {
  376. log.info(bucket.getKeyAsString() + "====" + bucket.getDocCount());
  377. }
  378. } catch (IOException e) {
  379. log.error("分桶聚合分析查询失败,错误信息:", e);
  380. }
  381. }
  382. /**
  383. * 子聚合聚合查询 Bucket 分桶聚合分析
  384. * <p>
  385. * 案例:根据商品分类进行分组查询,并且获取分类商品中的平均价格
  386. *
  387. * @param indexName 索引名
  388. * @param bucketField
  389. * @param bucketFieldAlias
  390. * @param avgFiled
  391. * @param avgFiledAlias
  392. */
  393. @Override
  394. public void subBucketQuery(String indexName, String bucketField, String bucketFieldAlias, String avgFiled, String avgFiledAlias) {
  395. try {
  396. /*构建查询条件*/
  397. MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
  398. /*创建查询源构造器*/
  399. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  400. searchSourceBuilder.query(matchAllQueryBuilder);
  401. /* 根据 bucketField进行分组查询,并且获取分类信息中 指定字段的平均值*/
  402. TermsAggregationBuilder subAggregation = AggregationBuilders.terms(bucketFieldAlias).field(bucketField)
  403. .subAggregation(AggregationBuilders.avg(avgFiledAlias).field(avgFiled));
  404. searchSourceBuilder.aggregation(subAggregation);
  405. /* 创建查询请求对象,将查询对象配置到其中*/
  406. SearchRequest searchRequest = new SearchRequest(indexName);
  407. searchRequest.source(searchSourceBuilder);
  408. /*执行查询,然后处理响应结果*/
  409. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  410. Aggregations aggregations = searchResponse.getAggregations();
  411. ParsedStringTerms aggBrandName1 = aggregations.get(bucketFieldAlias);
  412. for (Terms.Bucket bucket : aggBrandName1.getBuckets()) {
  413. /*获取聚合后的 组内字段平均值,注意返回值不是Aggregation对象,而是指定的ParsedAvg对象*/
  414. ParsedAvg avgPrice = bucket.getAggregations().get(avgFiledAlias);
  415. log.info(bucket.getKeyAsString() + "====" + avgPrice.getValueAsString());
  416. }
  417. } catch (IOException e) {
  418. log.error("分桶聚合分析查询失败,错误信息:", e);
  419. }
  420. }
  421. /**
  422. * 综合聚合查询
  423. * <p>
  424. * 根据商品分类聚合,获取每个商品类的平均价格,并且在商品分类聚合之上子聚合每个品牌的平均价格
  425. *
  426. * @param indexName 索引名
  427. */
  428. @Override
  429. public void subSubAgg(String indexName) {
  430. try {
  431. /*构建查询条件*/
  432. MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
  433. /*创建查询源构造器*/
  434. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  435. searchSourceBuilder.query(matchAllQueryBuilder);
  436. /*注意这里聚合写的位置不要写错,很容易搞混,错一个括号就不对了*/
  437. TermsAggregationBuilder subAggregation = AggregationBuilders.terms("categoryNameAgg").field("categoryName")
  438. .subAggregation(AggregationBuilders.avg("categoryNameAvgPrice").field("price"))
  439. .subAggregation(AggregationBuilders.terms("brandNameAgg").field("brandName")
  440. .subAggregation(AggregationBuilders.avg("brandNameAvgPrice").field("price")));
  441. searchSourceBuilder.aggregation(subAggregation);
  442. /*创建查询请求对象,将查询对象配置到其中*/
  443. SearchRequest searchRequest = new SearchRequest(indexName);
  444. searchRequest.source(searchSourceBuilder);
  445. /*执行查询,然后处理响应结果*/
  446. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  447. /*获取总记录数*/
  448. log.info("totalHits = " + searchResponse.getHits().getTotalHits().value);
  449. /*获取聚合信息*/
  450. Aggregations aggregations = searchResponse.getAggregations();
  451. ParsedStringTerms categoryNameAgg = aggregations.get("categoryNameAgg");
  452. /*获取值返回*/
  453. for (Terms.Bucket bucket : categoryNameAgg.getBuckets()) {
  454. /*获取聚合后的分类名称*/
  455. String categoryName = bucket.getKeyAsString();
  456. /*获取聚合命中的文档数量*/
  457. long docCount = bucket.getDocCount();
  458. /*获取聚合后的分类的平均价格,注意返回值不是Aggregation对象,而是指定的ParsedAvg对象*/
  459. ParsedAvg avgPrice = bucket.getAggregations().get("categoryNameAvgPrice");
  460. log.info(categoryName + "======平均价:" + avgPrice.getValue() + "======数量:" + docCount);
  461. ParsedStringTerms brandNameAgg = bucket.getAggregations().get("brandNameAgg");
  462. for (Terms.Bucket brandeNameAggBucket : brandNameAgg.getBuckets()) {
  463. /*获取聚合后的品牌名称*/
  464. String brandName = brandeNameAggBucket.getKeyAsString();
  465. /*获取聚合后的品牌的平均价格,注意返回值不是Aggregation对象,而是指定的ParsedAvg对象*/
  466. ParsedAvg brandNameAvgPrice = brandeNameAggBucket.getAggregations().get("brandNameAvgPrice");
  467. log.info(" " + brandName + "======" + brandNameAvgPrice.getValue());
  468. }
  469. }
  470. } catch (IOException e) {
  471. log.error("综合聚合查询失败,错误信息:", e);
  472. }
  473. }
  474. /**
  475. * 执行es查询
  476. *
  477. * @param indexName
  478. * @param beanClass
  479. * @param list
  480. * @param searchSourceBuilder
  481. * @param <T>
  482. * @throws IOException
  483. */
  484. private <T> void queryEsData(String indexName, Class<T> beanClass, List<T> list, SearchSourceBuilder searchSourceBuilder) throws IOException {
  485. /*创建查询请求对象,将查询对象配置到其中*/
  486. SearchRequest searchRequest = new SearchRequest(indexName);
  487. searchRequest.source(searchSourceBuilder);
  488. /*执行查询,然后处理响应结果*/
  489. SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  490. /*根据状态和数据条数验证是否返回了数据*/
  491. if (RestStatus.OK.equals(searchResponse.status()) && searchResponse.getHits().getTotalHits().value > 0) {
  492. SearchHits hits = searchResponse.getHits();
  493. for (SearchHit hit : hits) {
  494. /*将 JSON 转换成对象*/
  495. T bean = JSON.parseObject(hit.getSourceAsString(), beanClass);
  496. list.add(bean);
  497. }
  498. }
  499. }
  500. }