作者官方网站: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提供高效的反序列化,屏蔽底层复杂数据结构,给开发人员更高层的抽象
/*** 根据Id查询Es中的结果并转化为bean* @param request* @param targetClass* @return bean*/public static <T> T getById(EsQueryRq request,Class<T> targetClass){try{Client client =getEsClient();SearchRequestBuilder srb = client.prepareSearch(request.getIndex()).setTypes(request.getType());srb.setQuery(QueryBuilders.idsQuery().ids(request.getId()));SearchResponse searchResponse = srb.execute().actionGet(DEFUALT_TIME_OUT_MILLS);SearchHit[] hits = searchResponse.getHits().getHits();return JSON.parseObject(hits[0].getSourceAsString(), targetClass);}catch(Exception e){logger.error("err in es getById",e);}return null;}/*** 获取and map里面条件组成ES 识别的query* @param request* @return*/private static QueryBuilder getQueryByMatchAllMap(EsQueryRq request){Map<String,String> fieldMap = request.getMatchAllFieldValueMap();if (fieldMap!=null && !fieldMap.isEmpty()){BoolQueryBuilder bqb = QueryBuilders.boolQuery();Iterator<String> it = fieldMap.keySet().iterator();while(it.hasNext()){String key = it.next();bqb = bqb.must(QueryBuilders.termQuery(key, fieldMap.get(key)));}return bqb;}return null;}/*** 根据多个属性值查询ES结果,多个属性之间是 and关系* @param request* @param targetClass* @return list*/public static <T> List<T> getListByMatchAllMap(EsQueryRq request,Class<T> targetClass){QueryBuilder queryBuilder = getQueryByMatchAllMap(request);return getListByQuery(request,queryBuilder,targetClass);}/*** 获取or map里面条件组成ES 识别的query* @param request* @return*/private static QueryBuilder getQueryByMatchOneMap(EsQueryRq request){Map<String,String> fieldMap = request.getMatchOneFieldValueMap();if (fieldMap!=null && !fieldMap.isEmpty()){BoolQueryBuilder bqb = QueryBuilders.boolQuery();Iterator<String> it = fieldMap.keySet().iterator();while(it.hasNext()){String key = it.next();bqb = bqb.should(QueryBuilders.termQuery(key, fieldMap.get(key)));}return bqb;}return null;}/*** 根据多个属性值查询ES结果,多个属性之间是 or关系* @param request* @param targetClass* @return list*/public static <T> List<T> getListByMatchOneMap(EsQueryRq request,Class<T> targetClass){QueryBuilder queryBuilder = getQueryByMatchOneMap(request);return getListByQuery(request,queryBuilder,targetClass);}/*** 范围条件的查询,构造querBuilder对象* @param request* @return*/private static QueryBuilder getQueryByRangeList(EsQueryRq request){List<RangeQuery> rangeList = request.getMatchAllRangeList();if (rangeList != null) {BoolQueryBuilder bqb = QueryBuilders.boolQuery();for (RangeQuery query : rangeList){RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(query.getQueryName());setRangeValue(query,rangeQuery);bqb = bqb.must(rangeQuery);}return bqb;}return null;}private static void setRangeValue(RangeQuery query,RangeQueryBuilder rangeQueryBuilder){Method method;try {method = RangeQueryBuilder.class.getMethod(getMethodName(query), getParameter(query));method.setAccessible(true);method.invoke(rangeQueryBuilder, query.getValue());} catch (NoSuchMethodException | SecurityException e) {logger.error("err in EsQueryUtils reflect :",e);}catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {logger.error("err in EsQueryUtils reflect invocation :",e);}}private static String getMethodName(RangeQuery queryBean){switch (queryBean.getOperator()){case LT:return "lt";case LTE:return "lte";case GT:return "gt";case GTE:return "gte";default:return null;}}private static Class<?> getParameter(RangeQuery queryBean){switch (queryBean.getDataType()){case DATE:return Date.class;case LONG:return long.class;case DOUBLE:return double.class;case STRING:return String.class;}return String.class;}/*** 根据范围条件查询列表* @param request* @param targetClass* @return*/public static <T> List<T> getListByRange(EsQueryRq request,Class<T> targetClass){QueryBuilder queryBuilder = getQueryByRangeList(request);return getListByQuery(request,queryBuilder,targetClass);}/*** 根据自定义的queryBuilder查询ES 对象* @param request* @param queryBuilder* @param targetClass* @return*/public static <T> List<T> getListByQuery(EsQueryRq request,QueryBuilder queryBuilder,Class<T> targetClass){List<T> list = new ArrayList<>();try{if(queryBuilder !=null){SearchRequestBuilder srb = getEsClient().prepareSearch(request.getIndex()).setTypes(request.getType());//使用constantScoreQuery 去掉score功能,提高查询性能srb.setQuery(QueryBuilders.constantScoreQuery(queryBuilder));SearchResponse searchResponse = srb.execute().actionGet(DEFUALT_TIME_OUT_MILLS);SearchHit[] hits = searchResponse.getHits().getHits();for(SearchHit hit:hits){list.add(JSON.parseObject(hit.getSourceAsString(), targetClass));}}}catch(Exception e){logger.error("err in es getListByQuery:",e);}return list;}/*** 使用scroll 查询大数据量结果集* @param request* @param queryBuilder* @param callBack*/public static void doScanWithScroll(EsQueryRq request,QueryBuilder queryBuilder,ScrollReqCallBack callBack){SearchResponse scrollResp = null;try {scrollResp = getEsClient().prepareSearch(request.getIndex()).setTypes(request.getType()).setSearchType(SearchType.SCAN).setScroll(new TimeValue(SCROLL_KEEP_ALIVE_MILLS)).setQuery(queryBuilder).setSize(SCROLL_BATCH_SIZE_PER_SHARD)// hits per shard will be returned for each scroll.execute().actionGet();//Scroll until no hits are returnedwhile (true) {if(scrollResp != null){List<String> hitsList = new ArrayList<>();for (SearchHit hit : scrollResp.getHits().getHits()) {hitsList.add(hit.getSourceAsString());}callBack.doInScroll(hitsList);scrollResp = getEsClient().prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();//Break condition: No hits are returnedif (scrollResp.getHits().getHits().length == 0) {break;}}}} catch (Exception e) {logger.error("err in es doScanWithScroll:",e);}}/*** 获取每个查询项的列表,可以自行组装更复杂的查询条件* @param request* @return*/public static List<QueryBuilder> getAllQuery(EsQueryRq request){List<QueryBuilder> queryList = new ArrayList<>();queryList.add(getQueryByMatchAllMap(request));queryList.add(getQueryByMatchOneMap(request));queryList.add(getQueryByRangeList(request));return queryList;}/*** 组合所有条件,条件之间是 and 关系* @param request* @return*/public static QueryBuilder getCompoundQueryWithAnd(EsQueryRq request){List<QueryBuilder> queryList = getAllQuery(request);if ( !queryList.isEmpty()){BoolQueryBuilder bqb = QueryBuilders.boolQuery();for (QueryBuilder query : queryList){if (query != null){bqb = bqb.must(query);}}return bqb;}return null;}/*** 组合所有条件,条件之间是 or 关系* @param request* @return*/public static QueryBuilder getCompoundQueryWithOr(EsQueryRq request){List<QueryBuilder> queryList = getAllQuery(request);if (!queryList.isEmpty()){BoolQueryBuilder bqb = QueryBuilders.boolQuery();for (QueryBuilder query : queryList){if (query != null){bqb = bqb.should(query);}}return bqb;}return null;}
ElasticSearch高效查询实践
1420

被折叠的 条评论
为什么被折叠?



