es实体类:
java
public class ChemicalES {
@IndexId(type = IdType.CUSTOMIZE)
private Long id;
@HighLight
@IndexField(fieldType = FieldType.TEXT, analyzer = "ik_max_word")
private String name;
@IndexField(fieldType = FieldType.KEYWORD)
private List<String> productTags;
}
存入es中的查询结构:
现在希望对字段 productTags 进行聚合,想要聚合后结构如下:
bash
[
{key:'化肥',value:2},
{key:'农药',value:1},
{key:'尿素',value:2},
]
请教如何操作呢? 我用easy-es的api进行聚合一直报错。
解决方案:
因为这种方式叫做嵌套聚合,所以无法使用easy-es相关api,easy-es的groupBy只适合 key_word类型的 非数组属性的字段,而数组属性的字段 需要利用restHighLevelClient。
以下是通用代码示例:
java
@Autowired
public RestHighLevelClient restHighLevelClient;
/**
* [描述]
* @param indexName 索引名
* @param multiMatchQuery 多字段查询条件
* 示例: MultiMatchQueryBuilder multiMatchQuery = QueryBuilders.multiMatchQuery("测试", "title");
* @param fieldName 数组字段名
* @param fieldNameAs 聚合以后的数组字段别名
*
*/
private List<Map<Object,Object>> commonGroup( String indexName, MultiMatchQueryBuilder multiMatchQuery,
String fieldName,String fieldNameAs
) throws IOException {
SearchRequest request = new SearchRequest();
// 查询索引为nba的数据
request.indices(indexName);
// 对color字段进行分组
SearchSourceBuilder builder = new SearchSourceBuilder();
// 如果只关心分组数据,将结果集设置为0,即不展示hits中的数据
builder.size(0);
// 设置分组名称为`colorGroup`,并且结果数量进行排序,false:表示desc,true表示asc
AggregationBuilder aggregationBuilder = AggregationBuilders.terms(fieldNameAs)
.field(fieldName).order(BucketOrder.count(false));
builder.aggregation(aggregationBuilder);
if(multiMatchQuery != null){
builder.query(multiMatchQuery);
}
// 执行查询
request.source(builder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
// 获取数据
Aggregations aggregations = response.getAggregations();
ParsedStringTerms colorGroup = aggregations.get(fieldNameAs);
List<? extends Terms.Bucket> buckets = colorGroup.getBuckets();
List<Map<Object,Object>> result = new ArrayList<>();
for (Terms.Bucket bucket : buckets) {
Map<Object,Object> map =new HashMap<>(2);
System.out.println("name:" + bucket.getKey() + "," + "count:" + bucket.getDocCount());
map.put("name",bucket.getKey());
map.put("count",bucket.getDocCount());
result.add(map);
}
return result;
}