elasticsearch查询多字段聚合
1,需求:
在分页查询的同时,返回所查询商品的类目和品牌的聚合信息
2,mapping: { "item" : { "properties" : { "item_name" : { "type" : "string", "index" : "analyzed", "analyzer" : "ik_smart" }, "brand_name" : { "type" : "multi_field", "fields" : { "brand_name" : {"type" : "string", "index" : "analyzed", "analyzer" :"ik_smart"}, "brand_name_agg" : {"type" : "string", "index" : "not_analyzed"} } }, "c_name" : { "type" : "multi_field", "fields" : { "c_name" : {"type" : "string", "index" : "analyzed","analyzer" :"ik_smart"}, "c_name_agg" : {"type" : "string", "index" : "not_analyzed"} } } } } }
这里需要注意的是brand_name如果设置为ik分词,聚合结果也会进行分词,导致结果不准确
可对brand_name进行multi_field设置,query时使用brand_name,agg时使用brand_name_agg
3,查询时需要注意如果分别统计两个不相关的字段,可设置aggregations下多个结果集,若统计有父子关系的字段,
例如某年级下某班级的学生个数,可使用subAggregation功能
search:
{"from" : 0, "size" : 20, "query" : { "bool" : { "must" : { "fuzzy" : { "item_name" : { "value" : "西门子" } } } } }, "explain" : true, "aggregations" : { "brand_name.brand_name_agg" : { "terms" : { "field" : "brand_name.brand_name_agg", "size" : 9999, "order" : { "_count" : "asc" } } }, "c_name.c_name_agg" : { "terms" : { "field" : "c_name.c_name_agg", "size" : 9999, "order" : { "_count" : "asc" } } } } }
4,相关java实现方式:
1)查询条件构建:
SearchRequestBuilder builder = client.prepareSearch(index).setTypes(type);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
TermsBuilder termsBuilder = AggregationBuilders.terms(aggregation.getField());
termsBuilder.field(aggregation.getField());
if(SortConstant.SortASC.equals(aggregation.getOrder())){
termsBuilder.order(Terms.Order.aggregation("_count", true));
}else{
termsBuilder.order(Terms.Order.aggregation("_count", false));
}
termsBuilder.size(aggregation.getSize());
builder.addAggregation(termsBuilder);
2)查询结果返回:
Map<String,List<Object>> aggrMap = new HashMap<String, List<Object>>(); List<Aggregation> aggregationList = searchCondition.getAggregationList(); if(aggregationList!=null && aggregationList.size() > 0){ for(Aggregation aggregation : aggregationList){ List<Object> results = new ArrayList<Object>(); Terms result = searchResponse.getAggregations().get(aggregation.getField()); for (Terms.Bucket entry : result.getBuckets()) { results.add(entry.getKey()); } aggrMap.put(aggregation.getField(),results); } }
5,参考资料: http://www.cnblogs.com/xing901022/p/4947436.html?utm_source=tuicool&utm_medium=referral http://blog..net/xiaohelong2005/article/details/41513985 http://www.cnblogs.com/sha0830/p/5549331.html
