简单聚合查询:
获取到已将初始化成功的客户端连接
1、多条件组合聚合查询(可用于查询条件内的数据数量)
此处使用与查询,且条件筛选为termsQuery,类似以mysql中的in查询。
public Long sum(HashMap<String, List<String>> map) { TransportClient client = esConfiguration.transportClient(); SearchResponse sr = new SearchResponse(); try { if (map.size() == 0) { sr = client.prepareSearch(index).setSize(0).execute().actionGet(); return sr.getHits().getTotalHits(); } } catch (Exception e) { } BoolQueryBuilder mustQuery = QueryBuilders.boolQuery(); for (String filed : map.keySet()) { List<String> list = map.get(filed); String[] strings = new String[list.size()]; list.toArray(strings); mustQuery.must(QueryBuilders.termsQuery(filed, strings)); } SearchRequestBuilder searchRequestBuilder = esConfiguration.transportClient().prepareSearch(index) .setTypes(type).setQuery(mustQuery); SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); Long hitNum = searchResponse.getHits().getTotalHits(); return hitNum; }
2、双层聚合查询(产出数据为二维)
/** * 功能描述: * * @param: mustQuery(用于查询的条件),field(用户聚合的字段) * @return: HashMap<String, List<TreeMap<String,String>>> * @auther: dub * @date: 2018-12-24 18:46 * @desc: 双层聚合 */ public HashMap<String, List<TreeMap<String, String>>> eveSum(BoolQueryBuilder mustQuery, String field) { HashMap<String, List<HashMap<String, String>>> resultMap = new HashMap<>(); HashMap<String, List<TreeMap<String, String>>> returnMap = new HashMap<>(); TransportClient client = esConfiguration.transportClient(); try { mustQuery.must(QueryBuilders.matchAllQuery()); // 匹配所有文档 SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type).setQuery(mustQuery); String[] split = field.split(","); TermsAggregationBuilder teSex = AggregationBuilders.terms(split[0]).field(split[0]); TermsAggregationBuilder teRange = AggregationBuilders.terms(split[1]).field(split[1]); teSex.subAggregation(teRange); searchRequestBuilder.addAggregation(teSex); // 聚合查询(分组查询) Terms terms = searchRequestBuilder.get().getAggregations().get(split[0]); if (terms.getBuckets() == null || terms.getBuckets().size() == 0) { return returnMap; } for (Terms.Bucket sex_name : terms.getBuckets()) { Terms terms_range = sex_name.getAggregations().get(split[1]); ArrayList<HashMap<String, String>> list = new ArrayList<>(); for (Terms.Bucket range_name : terms_range.getBuckets()) { HashMap<String, String> map = new HashMap<>(); map.put((String) range_name.getKey(), String.valueOf(range_name.getDocCount())); list.add(map); } resultMap.put((String) sex_name.getKey(), list); } for (String str : resultMap.keySet()) { List<HashMap<String, String>> list = resultMap.get(str); ArrayList<TreeMap<String, String>> treeMaps = new ArrayList<>(); HashMap<String, String> map1 = new HashMap<>(); // 临时map for (HashMap<String, String> map : list) { // 先把所有的map放到一个map中 for (String s : map.keySet()) { map1.put(s, map.get(s)); } } TreeMap<String, String> stringStringMap = (TreeMap<String, String>) MapUtil.sortMapByKey(map1); treeMaps.add(stringStringMap); returnMap.put(str, treeMaps); } } catch (Exception e) { e.printStackTrace(); } return returnMap; }
3、单层聚合查询
/** * 功能描述: * * @param: mustQuery(用于查询的条件),field(用户聚合的字段) * @return: List<HashMap<Object,Object>> * @auther: dub * @date: 2018-12-24 18:42 * @desc: 单层聚合 */ public List<HashMap<Object, Object>> aggre(BoolQueryBuilder mustQuery, String field) { ArrayList<HashMap<Object, Object>> resultList = new ArrayList<>(); TransportClient client = esConfiguration.transportClient(); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type).setQuery(mustQuery); try { TermsAggregationBuilder teSex = AggregationBuilders.terms("count").field(field); searchRequestBuilder.addAggregation(teSex); } catch (Exception e) { e.printStackTrace(); return resultList; } // 聚合查询(分组查询) try { Terms terms = searchRequestBuilder.get().getAggregations().get("count"); if (terms.getBuckets().size() > 0) { for (Terms.Bucket sex_name : terms.getBuckets()) { HashMap<Object, Object> resultMap = new HashMap<>(); resultMap.put(sex_name.getKey(), sex_name.getDocCount()); resultList.add(resultMap); } } } catch (Exception e) { e.printStackTrace(); return resultList; } return resultList; }
4、模糊查询(此处的模糊查询未做分词查询,仅仅使用聚合模糊匹配)
/** * 功能描述: * * @param: filed * @return: List<String> * @auther: dub * @date: 2018-12-24 15:45 * @desc: 根据字段模糊搜索 */ public List<String> fuzzy(String filed, String attr) { TransportClient client = esConfiguration.transportClient(); List<String> resultList = new LinkedList<>(); try { BoolQueryBuilder mustQuery = QueryBuilders.boolQuery(); mustQuery.must(QueryBuilders.wildcardQuery(filed, "*" + attr + "*")); TermsAggregationBuilder teSex = AggregationBuilders.terms("prop_count").field(filed); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type).setQuery(mustQuery) .setSize(100); searchRequestBuilder.addAggregation(teSex); Terms terms = searchRequestBuilder.get().getAggregations().get("prop_count"); if (terms.getBuckets().size() > 0) { for (Terms.Bucket value : terms.getBuckets()) { resultList.add(value.getKey().toString()); } } } catch (Exception e) { logger.error(e.getMessage()); } return resultList; }
5、分页查询(游标分页查询)
注:es的分页查询有两种。第一种from to查询只能查询10000条记录,且是所有分片数据,可能存在重复数据,此方式多适用于做数据示例展示。
第二种为游标查询:es的游标查询第一次不返回数据,只返回游标;第二次需携带第一次返回的游标查询数据,并返回设置的返回文档数据和游标,并将游标移至下一个开始的分割点。以此类推,可以查询条件范围内的所有文档。
游标的详细使用方法请参考官方,此处仅介绍使用方式。另需特别注意的是,每次游标查询时需使用同一个客户端连接,否则会导致游标重置。
public HashMap<String, Object> getSimpleSearchResponse(BoolQueryBuilder mustQuery, String[] fetchSource, String scollId) { TransportClient client = esConfiguration.transportClient(); HashMap<String, Object> resultMap = new HashMap<>(); List<Map<String, Object>> sourceList = new ArrayList<>(); SearchResponse response = null; if (RString.isBlank(scollId)) { //第一次游標查詢 response = client.prepareSearch(index).setTypes(type).setSize(1000).setQuery(mustQuery) .setScroll(TimeValue.timeValueMinutes(1)).addSort("_doc", SortOrder.DESC) .setFetchSource(fetchSource, null).execute().actionGet(); resultMap.put("scollId", response.getScrollId()); for (SearchHit searchHit : response.getHits().getHits()) { sourceList.add(searchHit.getSourceAsMap()); } resultMap.put("data", sourceList); return resultMap; } //非第一次 return getByScoll(scollId, client); } /** * 分页 * * @param scollId * @return HashMap<String, Object> */ private HashMap<String, Object> getByScoll(String scollId, TransportClient client) { HashMap<String, Object> resultMap = new HashMap<>(); List<Map<String, Object>> sourceList = new ArrayList<>(); SearchResponse response = client.prepareSearchScroll(scollId).setScroll(TimeValue.timeValueMinutes(1)).execute() .actionGet(); SearchHit[] s = response.getHits().getHits(); if (s == null || s.length == 0) { return null; } for (SearchHit searchHit : response.getHits().getHits()) { sourceList.add(searchHit.getSourceAsMap()); } resultMap.put("scollId", response.getScrollId()); resultMap.put("hitNum", sourceList.size()); resultMap.put("data", sourceList); return resultMap; }
6、统计查询
/** * 功能描述: * * @param: * @return: * @auther: dub * @date: 2018-12-12 15:39 * @desc: 获取命中总数 */ public Long count(BoolQueryBuilder mustQuery, String[] fetchSource) { mustQuery.must(QueryBuilders.matchAllQuery()); // 添加第1条must的条件 此处为匹配所有文档 TransportClient client = esConfiguration.transportClient(); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type) .setFetchSource(fetchSource, null) // 设置查询条件 .setQuery(mustQuery); SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); long totalHits = searchResponse.getHits().getTotalHits(); // 打印命中数量 logger.info("命中数量:" + totalHits); return totalHits; }
7、根据单条件筛选文档记录
/** * 功能描述: * * @param: * @return: * @auther: dub * @date: 2018-12-13 14:18 * @desc: 根据某个字段查询文档 */ public SearchResponse getDocumentByCoulmn(BoolQueryBuilder mustQuery) { mustQuery.must(QueryBuilders.matchAllQuery()); // 添加第1条must的条件 此处为匹配所有文档 TransportClient client = esConfiguration.transportClient(); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index).setTypes(type) // 设置查询条件 .setQuery(mustQuery); SearchResponse searchResponse = searchRequestBuilder.execute().actionGet(); return searchResponse; }