ElasticSearch查询

作者官方网站:http://www.wxl568.cn

ElasticSearch查询工具提供高效,方便易用的查询接口,满足用户灵活多变的查询功能

ElasticSearch是一款分布式的全文检索工具,支持对文本和结构化数据的查询。虽然ES很强大,但开发人员如果要去使用它需要

熟悉相关原理和查询语法,即使这样,要高效的使用它还需要积累相关的经验。

ElasticSearch查询工具可以在很大程度上提高开发人员效率,

提供高效的查询方式,同时提供灵活的查询条件组合模式。

1.ElasticSearch查询工具支持的检索操作符
and (&&)
or (||)
larger (>)
larger or equal to(>=)
less (<)
less or equal to(<=)
in

2.ElasticSearch查询的数据类型
long
double
date
string

3.同时支持查询条件组合

4.ES查询工具通过Scroll和回调函数的方式支持大数据量的检索

5.通过alibaba的fastjson提供高效的反序列化,屏蔽底层复杂数据结构,给开发人员更高层的抽象

 
  1. /**
  2. * 根据Id查询Es中的结果并转化为bean
  3. * @param request
  4. * @param targetClass
  5. * @return bean
  6. */
  7. public static <T> T getById(EsQueryRq request,Class<T> targetClass){
  8. try{
  9. Client client =getEsClient();
  10.  
  11. SearchRequestBuilder srb = client.prepareSearch(request.getIndex())
  12. .setTypes(request.getType());
  13. srb.setQuery(QueryBuilders.idsQuery().ids(request.getId()));
  14. SearchResponse searchResponse = srb.execute().actionGet(DEFUALT_TIME_OUT_MILLS);
  15. SearchHit[] hits = searchResponse.getHits().getHits();
  16. return JSON.parseObject(hits[0].getSourceAsString(), targetClass);
  17. }catch(Exception e){
  18. logger.error("err in es getById",e);
  19. }
  20. return null;
  21. }
  22.  
  23.  
  24. /**
  25. * 获取and map里面条件组成ES 识别的query
  26. * @param request
  27. * @return
  28. */
  29. private static QueryBuilder getQueryByMatchAllMap(EsQueryRq request){
  30. Map<String,String> fieldMap = request.getMatchAllFieldValueMap();
  31. if (fieldMap!=null && !fieldMap.isEmpty()){
  32. BoolQueryBuilder bqb = QueryBuilders.boolQuery();
  33. Iterator<String> it = fieldMap.keySet().iterator();
  34. while(it.hasNext()){
  35. String key = it.next();
  36. bqb = bqb.must(QueryBuilders.termQuery(key, fieldMap.get(key)));
  37. }
  38. return bqb;
  39. }
  40. return null;
  41. }
  42.  
  43. /**
  44. * 根据多个属性值查询ES结果,多个属性之间是 and关系
  45. * @param request
  46. * @param targetClass
  47. * @return list
  48. */
  49. public static <T> List<T> getListByMatchAllMap(EsQueryRq request,Class<T> targetClass){
  50. QueryBuilder queryBuilder = getQueryByMatchAllMap(request);
  51. return getListByQuery(request,queryBuilder,targetClass);
  52. }
  53.  
  54.  
  55. /**
  56. * 获取or map里面条件组成ES 识别的query
  57. * @param request
  58. * @return
  59. */
  60. private static QueryBuilder getQueryByMatchOneMap(EsQueryRq request){
  61. Map<String,String> fieldMap = request.getMatchOneFieldValueMap();
  62. if (fieldMap!=null && !fieldMap.isEmpty()){
  63. BoolQueryBuilder bqb = QueryBuilders.boolQuery();
  64. Iterator<String> it = fieldMap.keySet().iterator();
  65. while(it.hasNext()){
  66. String key = it.next();
  67. bqb = bqb.should(QueryBuilders.termQuery(key, fieldMap.get(key)));
  68. }
  69. return bqb;
  70. }
  71. return null;
  72. }
  73.  
  74.  
  75. /**
  76. * 根据多个属性值查询ES结果,多个属性之间是 or关系
  77. * @param request
  78. * @param targetClass
  79. * @return list
  80. */
  81. public static <T> List<T> getListByMatchOneMap(EsQueryRq request,Class<T> targetClass){
  82. QueryBuilder queryBuilder = getQueryByMatchOneMap(request);
  83. return getListByQuery(request,queryBuilder,targetClass);
  84. }
  85.  
  86.  
  87. /**
  88. * 范围条件的查询,构造querBuilder对象
  89. * @param request
  90. * @return
  91. */
  92. private static QueryBuilder getQueryByRangeList(EsQueryRq request){
  93. List<RangeQuery> rangeList = request.getMatchAllRangeList();
  94. if (rangeList != null) {
  95. BoolQueryBuilder bqb = QueryBuilders.boolQuery();
  96. for (RangeQuery query : rangeList){
  97. RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(query.getQueryName());
  98. setRangeValue(query,rangeQuery);
  99. bqb = bqb.must(rangeQuery);
  100. }
  101. return bqb;
  102. }
  103. return null;
  104. }
  105.  
  106. private static void setRangeValue(RangeQuery query,RangeQueryBuilder rangeQueryBuilder){
  107. Method method;
  108. try {
  109. method = RangeQueryBuilder.class.getMethod(getMethodName(query), getParameter(query));
  110. method.setAccessible(true);
  111. method.invoke(rangeQueryBuilder, query.getValue());
  112. } catch (NoSuchMethodException | SecurityException e) {
  113. logger.error("err in EsQueryUtils reflect :",e);
  114. }
  115. catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
  116. logger.error("err in EsQueryUtils reflect invocation :",e);
  117. }
  118. }
  119.  
  120. private static String getMethodName(RangeQuery queryBean){
  121. switch (queryBean.getOperator()){
  122. case LT:
  123. return "lt";
  124. case LTE:
  125. return "lte";
  126. case GT:
  127. return "gt";
  128. case GTE:
  129. return "gte";
  130. default:
  131. return null;
  132. }
  133. }
  134.  
  135. private static Class<?> getParameter(RangeQuery queryBean){
  136. switch (queryBean.getDataType()){
  137. case DATE:
  138. return Date.class;
  139. case LONG:
  140. return long.class;
  141. case DOUBLE:
  142. return double.class;
  143. case STRING:
  144. return String.class;
  145. }
  146. return String.class;
  147. }
  148.  
  149.  
  150. /**
  151. * 根据范围条件查询列表
  152. * @param request
  153. * @param targetClass
  154. * @return
  155. */
  156. public static <T> List<T> getListByRange(EsQueryRq request,Class<T> targetClass){
  157. QueryBuilder queryBuilder = getQueryByRangeList(request);
  158. return getListByQuery(request,queryBuilder,targetClass);
  159. }
  160.  
  161. /**
  162. * 根据自定义的queryBuilder查询ES 对象
  163. * @param request
  164. * @param queryBuilder
  165. * @param targetClass
  166. * @return
  167. */
  168. public static <T> List<T> getListByQuery(EsQueryRq request,QueryBuilder queryBuilder,Class<T> targetClass){
  169. List<T> list = new ArrayList<>();
  170. try{
  171. if(queryBuilder !=null){
  172. SearchRequestBuilder srb = getEsClient().prepareSearch(request.getIndex())
  173. .setTypes(request.getType());
  174. //使用constantScoreQuery 去掉score功能,提高查询性能
  175. srb.setQuery(QueryBuilders.constantScoreQuery(queryBuilder));
  176. SearchResponse searchResponse = srb.execute().actionGet(DEFUALT_TIME_OUT_MILLS);
  177. SearchHit[] hits = searchResponse.getHits().getHits();
  178.  
  179. for(SearchHit hit:hits){
  180. list.add(JSON.parseObject(hit.getSourceAsString(), targetClass));
  181. }
  182. }
  183. }catch(Exception e){
  184. logger.error("err in es getListByQuery:",e);
  185. }
  186. return list;
  187. }
  188.  
  189. /**
  190. * 使用scroll 查询大数据量结果集
  191. * @param request
  192. * @param queryBuilder
  193. * @param callBack
  194. */
  195. public static void doScanWithScroll(EsQueryRq request,QueryBuilder queryBuilder,ScrollReqCallBack callBack){
  196. SearchResponse scrollResp = null;
  197. try {
  198. scrollResp = getEsClient().prepareSearch(request.getIndex()).setTypes(request.getType())
  199. .setSearchType(SearchType.SCAN)
  200. .setScroll(new TimeValue(SCROLL_KEEP_ALIVE_MILLS))
  201. .setQuery(queryBuilder)
  202. .setSize(SCROLL_BATCH_SIZE_PER_SHARD)// hits per shard will be returned for each scroll
  203. .execute().actionGet();
  204.  
  205. //Scroll until no hits are returned
  206. while (true) {
  207. if(scrollResp != null){
  208. List<String> hitsList = new ArrayList<>();
  209. for (SearchHit hit : scrollResp.getHits().getHits()) {
  210. hitsList.add(hit.getSourceAsString());
  211. }
  212. callBack.doInScroll(hitsList);
  213.  
  214. scrollResp = getEsClient().prepareSearchScroll(scrollResp.getScrollId())
  215. .setScroll(new TimeValue(60000)).execute().actionGet();
  216.  
  217. //Break condition: No hits are returned
  218. if (scrollResp.getHits().getHits().length == 0) {
  219. break;
  220. }
  221. }
  222. }
  223. } catch (Exception e) {
  224. logger.error("err in es doScanWithScroll:",e);
  225. }
  226. }
  227.  
  228. /**
  229. * 获取每个查询项的列表,可以自行组装更复杂的查询条件
  230. * @param request
  231. * @return
  232. */
  233. public static List<QueryBuilder> getAllQuery(EsQueryRq request){
  234. List<QueryBuilder> queryList = new ArrayList<>();
  235. queryList.add(getQueryByMatchAllMap(request));
  236. queryList.add(getQueryByMatchOneMap(request));
  237. queryList.add(getQueryByRangeList(request));
  238. return queryList;
  239. }
  240.  
  241. /**
  242. * 组合所有条件,条件之间是 and 关系
  243. * @param request
  244. * @return
  245. */
  246. public static QueryBuilder getCompoundQueryWithAnd(EsQueryRq request){
  247. List<QueryBuilder> queryList = getAllQuery(request);
  248. if ( !queryList.isEmpty()){
  249. BoolQueryBuilder bqb = QueryBuilders.boolQuery();
  250. for (QueryBuilder query : queryList){
  251. if (query != null){
  252. bqb = bqb.must(query);
  253. }
  254. }
  255. return bqb;
  256. }
  257. return null;
  258. }
  259.  
  260. /**
  261. * 组合所有条件,条件之间是 or 关系
  262. * @param request
  263. * @return
  264. */
  265. public static QueryBuilder getCompoundQueryWithOr(EsQueryRq request){
  266. List<QueryBuilder> queryList = getAllQuery(request);
  267. if (!queryList.isEmpty()){
  268. BoolQueryBuilder bqb = QueryBuilders.boolQuery();
  269. for (QueryBuilder query : queryList){
  270. if (query != null){
  271. bqb = bqb.should(query);
  272. }
  273. }
  274. return bqb;
  275. }
  276. return null;
  277. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值