业务需求
- 需要获取分组列表,查询返回值不是一个列表,而是根据某个字段分组
- 每组返回前5条,不足5条,则返回全部
- 按照时间倒序
实现
- elasticsearch提供了
top_hits 聚合函数,支持返回前几条 TermsAggregationBuilder 和TopHitsAggregationBuilder 2个聚合函数结合使用,实现该效果
java代码
@Override
public Map<String, Object> aggregateTopHitsByField(PolicyContentQuerySynVO queryVO) {
Map<String, Object> result = new HashedMap();
SearchRequestBuilder builder = elasticsearchTemplate.getClient()
.prepareSearch(POLICY_INDEX_NAME).setTypes(POLICY_TYPE_NAME);
SearchCondition searchCondition = searchCondition(queryVO);
builder.setQuery(searchCondition.getQueryBuilder());
builder.setFetchSource(false);
TermsAggregationBuilder aggregation = AggregationBuilders.terms(queryVO.getAggregateKey()+"_arr")
.field(queryVO.getAggregateKey());
if(queryVO.getAggregateOrder() != null){
aggregation.order(Terms.Order.count(queryVO.getAggregateOrder()));
}
if(null != queryVO.getAggregateSize()){
aggregation.size(queryVO.getAggregateSize());
}else {
aggregation.size(2000);
}
TopHitsAggregationBuilder topHitsAggregationBuilder = AggregationBuilders.topHits(queryVO.getAggregateKey());
if(null != queryVO.getAggregateTopHitSize()){
topHitsAggregationBuilder.size(queryVO.getAggregateTopHitSize());
}else {
topHitsAggregationBuilder.size(10);
}
String sortField = queryVO.getSortField();
if(Ls.isEmpty(sortField)){
sortField = SORT_FIELD;
}
if("desc".equals(queryVO.getSortOrder())){
topHitsAggregationBuilder.sort(sortField, SortOrder.DESC);
}else {
topHitsAggregationBuilder.sort(sortField, SortOrder.ASC);
}
aggregation.subAggregation(topHitsAggregationBuilder);
builder = builder.addAggregation(aggregation).setSize(0);
logger.info("aggregateTopHitsByField:: builder:\n{}",builder);
SearchResponse response = builder.get();
if(response != null){
String bucketKey = queryVO.getAggregateKey()+"_arr";
Terms terms = response.getAggregations().get(bucketKey);
Map<String,Long> countMap = new LinkedHashMap();
Map<String,List<Object>> infoMap = new LinkedHashMap();
for (Terms.Bucket entry1 : terms.getBuckets()) {
String key = entry1.getKey().toString();
Long docCount = entry1.getDocCount();
countMap.put(key,docCount);
TopHits topHits = entry1.getAggregations().get("level");
List<Object> topResult = new ArrayList<>();
for(SearchHit hit : topHits.getHits()){
Map<String, Object> resultMap = new HashedMap();
for (Map.Entry<String, Object> entry : hit.getSource().entrySet()) {
if(entry.getValue() == null){
continue;
}
resultMap.put(entry.getKey(),String.valueOf(entry.getValue()));
}
topResult.add(resultMap);
}
infoMap.put(key,topResult);
}
result.put(bucketKey + "_count",countMap);
result.put(bucketKey + "_info",infoMap);
}
return result;
}
kibana请求体
- 也可以使用
kibana 等工具测试,或者直接curl 测试
GET /policylibrary/info/_search
{
"size": 0,
"query": {
"bool": {
"must": [
{
"term": {
"isPublish": {
"value": 1,
"boost": 1
}
}
},
{
"term": {
"topicIds.keyword": {
"value": 100041,
"boost": 1
}
}
}
],
"disable_coord": false,
"adjust_pure_negative": true,
"boost": 1
}
},
"_source": false,
"aggregations": {
"level_arr": {
"terms": {
"field": "level",
"size": 2000,
"min_doc_count": 1,
"shard_min_doc_count": 0,
"show_term_doc_count_error": false,
"order": [
{
"_count": "desc"
},
{
"_term": "asc"
}
]
},
"aggregations": {
"level": {
"top_hits": {
"from": 0,
"size": 6,
"version": false,
"explain": false,
"sort": [
{
"publishDate": {
"order": "desc"
}
}
],
"_source" : {
"includes" : [],
"excludes" : ["content"]
}
}
}
}
}
}
}
返回示例
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 3,
"successful": 3,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 0,
"hits": []
},
"aggregations": {
"level_arr": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 2,
"doc_count": 2,
"level": {
"hits": {
"total": 2,
"max_score": null,
"hits": [
{
"_index": "policylibrary",
"_type": "info",
"_id": "100000911",
"_score": null,
"_source": {
"publishDate": "2021-05-27 19:16:13",
"title": "安徽省人民政府办公厅关于推进社会保障卡建设的通知",
"url": "http://192.168.1.73:7381/site/tpl/5021?id=100000911"
},
"sort": [
1622142973000
]
},
{
"_index": "policylibrary",
"_type": "info",
"_id": "100000651",
"_score": null,
"_source": {
"publishDate": "2021-03-15 15:15:25",
"title": "安徽省人民政府办公厅关于印发支持凹凸棒基新材料产业发展若干政策的通知",
"url": "http://192.168.1.73:7381/site/tpl/5021?id=100000651"
},
"sort": [
1615821325000
]
}
]
}
}
},
{
"key": 1,
"doc_count": 1,
"level": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "policylibrary",
"_type": "info",
"_id": "100000901",
"_score": null,
"_source": {
"publishDate": "2021-05-27 19:11:35",
"title": "人力资源和社会保障部关于印发“中华人民共和国社会保障卡”管理办法的通知",
"url": "http://192.168.x.xx:7381/site/tpl/5021?id=100000901"
},
"sort": [
1622142695000
]
}
]
}
}
},
{
"key": 3,
"doc_count": 1,
"level": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "policylibrary",
"_type": "info",
"_id": "100000931",
"_score": null,
"_source": {
"publishDate": "2021-07-05 15:31:25",
"title": "建党100周年",
"url": "http://192.168.x.xx:7381/site/tpl/5021?id=100000931"
},
"sort": [
1625499085000
]
}
]
}
}
}
]
}
}
}
|