本文目录
1 功能简介
2 使用示例
(1)场景示例:
(2)ES查询示例:
(3)Java查询示例:
3 相关文章
官方文档
聚合后,每一个聚合Bucket里面仅返回指定顺序的前N条数据。
ES库中存储着成员数据,每个成员有自己的编号ID、所属的团队ID和个人得分等数据:id, team_id, score, age...
给定一组团队ID列表:team_id IN (1, 5, 7)
查询每个团队中得分最高的2个人的编号ID。
GET .../_search?routing=xxx // 若已知数据属于某一个或几个路由分区,设置路由会提升性能。
{
"size": 0, // 仅过滤数据,不返回命中数据。
"query": {
"bool": {
"filter": [ // 过滤条件,在聚合前先进行数据筛选。
{
"terms": {
"team_id": [
1,
5,
7
]
}
}
]
}
},
"aggs": {
"group_aggs": { // 第一层聚合:先按照team_id将数据聚合成多个Bucket。
"terms": {
"field": "team_id",
"execution_hint": "map" // 若可知该层聚合结果数量很小,设置成map可提升性能。
},
"aggs": {
"top_score_member": { // 第二层聚合:在第一层聚合结果中的每个Bucket内,在进行top_hits聚合操作。
"top_hits": {
"size": 2, // 仅返回前2条记录
"sort": [ // 排序条件按照score倒序
{
"score": {
"order": "desc"
}
}
]
}
}
}
}
}
}
TransportClient 版本示例:
// 过滤条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.filter(QueryBuilders.termsQuery("team_id", Lists.newArrayList(1, 3, 5)));
// 聚合条件
AggregationBuilder groupAggBuilder = AggregationBuilders.terms("group_aggs")
.field("team_id")
.executionHint("map"); // 若可知该层聚合结果数量很小,设置成map可提升性能。
AggregationBuilder topScoreAggBuilder = AggregationBuilders.topHits("top_score_member")
.sort("score", SortOrder.DESC)
.size(2);
groupAggBuilder.subAggregation(topScoreAggBuilder);
// 查询结果
SearchResponse response = transportClient.prepareSearch("index_name").setTypes("type_name")
.setRouting("xxx") // 若已知数据属于某一个或几个路由分区,设置路由会提升性能。
.setSize(0)
.setQuery(boolQueryBuilder)
.addAggregation(groupGoodsAggBuilder)
.get();
RestHighLevelClient 示例:
// 过滤条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.filter(QueryBuilders.termsQuery("team_id", Lists.newArrayList(1, 3, 5)));
// 聚合条件
AggregationBuilder groupAggBuilder = AggregationBuilders.terms("group_aggs")
.field("team_id")
.executionHint("map"); // 若可知该层聚合结果数量很小,设置成map可提升性能。
AggregationBuilder topScoreAggBuilder = AggregationBuilders.topHits("top_score_member")
.sort("score", SortOrder.DESC)
.size(2);
groupAggBuilder.subAggregation(topScoreAggBuilder);
// 构造查询对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.size(0);
searchSourceBuilder.aggregation(groupGoodsAggBuilder);
// 观察线上接口响应情况,设置合理的超时时间。
searchSourceBuilder.timeout(new TimeValue(300));
SearchRequest request = new SearchRequest("index_name")
request.source(searchSourceBuilder);
request.setRouting("xxx") // 若已知数据属于某一个或几个路由分区,设置路由会提升性能。
// 请求数据
SearchResponse searchResponse = restHighLevelClient.search(request, RequestOptions.DEFAULT);
SearchResponse 解析示例:
if (Objects.nonNull(response) && Objects.equals(response.status(), RestStatus.OK)) {
Terms groupResult = response.getAggregations().get("group_aggs");
if (Objects.nonNull(groupResult)) {
for (Terms.Bucket groupBucket : groupResult.getBuckets()) {
TopHits topScoreResult = groupBucket.getAggregations().get("top_score_member");
if (Objects.nonNull(topScoreResult) && topScoreResult.getHits().getHits().length > 0) {
SearchHit searchHit = topScoreResult.getHits().getAt(0);
MemberDTO top1Member = JSON.parseObject(searchHit.getSourceAsString(), MemberDTO.class);
SearchHit searchHit = topScoreResult.getHits().getAt(1);
MemberDTO top2Member = JSON.parseObject(searchHit.getSourceAsString(), MemberDTO.class);
// 其它逻辑
}
}
}
}
《ElasticSearch 学习笔记:常用内容》
《ElasticSearch 学习笔记:Multi Search》
《ElasticSearch 学习笔记:Mapping》
《ElasticSearch 学习笔记:Reindex》
ElasticSearch Top Hits Aggregation