elasticsearch复杂查询的API使用

简单聚合查询:

获取到已将初始化成功的客户端连接

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值