注意:
- es版本至少6.1以上
先看一下es存储的数据情况,我们需要通过pid去重并且实现分页
先贴出Es的代码
{
// 这里是对hits的数据进行限制只返回一条数据,因为我不要这里的数据,所以避免数据过多就直接返回最小
"from":0,
"size":1,
"query":{
"match_all":{
"boost":1
}
},
"aggregations":{
"agg":{
"terms":{
"field":"pid",
//这里代表聚合查询出多少条数据,注意这里的size要比最下面分页的size要大,因为是对聚合后的数据分页,如果不写的话默认是10
"size":10
},
"aggregations":{
"top":{
"top_hits":{
"from":0,
// 这里的size表示重复的返回几条,这里我们返回1
"size":1,
"version":false,
"seq_no_primary_term":false,
"explain":false,
"_source":{
"includes":[
// 这个是需要返回的字段
"pid"
],
"excludes":[
]
}
}
},
"bucket_field":{
"bucket_sort":{
"sort":[
],
// 这里是聚合分页从第几页开始,每页多少条(举个列子第一页(0,10),第二页就是(10,20))
"from":0,
"size":10
}
}
}
}
}
}
Java 代码
//构造查询器
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //查询条件查询所有 QueryBuilder queryBuilders = QueryBuilders.matchAllQuery(); // 需要返回字段的集合 String[] param= {"pid"}; // 对需要返回的数据包括哪些,不包括哪些,重复的只返回1条 TopHitsAggregationBuilder top1 = AggregationBuilders.topHits("top").fetchSource(param, Strings.EMPTY_ARRAY).size(1);
// 通过pid聚合并且聚合后返回10条数据,注意这里的size(这里代表聚合查询出多少条数据,注意这里的size要比最下面分页的size要大,因为是对聚合后的数据分页,如果不写的话默认是10) TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("agg").field("pid").subAggregation(top1).size(10); // 聚合分页 termsAggregationBuilder.subAggregation(new BucketSortPipelineAggregationBuilder("bucket_field",null).from(0).size(10)); // 这里的.from(0).size(1) 表示最外层hits返回的数据 searchSourceBuilder.query(queryBuilders).aggregation(termsAggregationBuilder).from(0).size(1); //解析返回的数据
SearchResponse response = getSearchResponse(searchSourceBuilder); Terms agg = response.getAggregations().get("agg"); for (Terms.Bucket bucket : agg.getBuckets()) { TopHits top = bucket.getAggregations().get("top"); for (SearchHit searchHit : top.getHits()) { System.out.println(searchHit.getSourceAsMap()); } } // 执行查询并且返回response
private SearchResponse getSearchResponse(SearchSourceBuilder searchSourceBuilder) { // 注入自己的es进行查询 SearchResponse response = esTemplate.query("distinct_test_es","dgg_doc", searchSourceBuilder); return response; }
最后结果为已去重,并且可以分页