目录
介绍
实际操作
DSL实现Metrics聚合(嵌套聚合)
RestClient实现聚合(以酒店品牌为例)
实现对酒店品牌、城市、星级的过滤
补6.20:
(32条消息) Elasticsearch 聚合查询(aggs)_龙源lll的博客-CSDN博客_elasticsearch聚合查询
介绍
聚合:实现对文档数据的统计、分析以及运算,类似于分组group by
既然是完成数据的统计,说明我们的文档中聚合字段类型是不能分词,type不能是text,不然你一种字段来了好几个,不能分组;
所以说参与聚合的字段类型:可以是keyword(不参与分词)、日期and布尔类型的等等;
聚合三要素:聚合名称、聚合类型、聚合字段
聚合可配置的属性:
实际操作
GET /hotel/_search
{
"size": 0,
"aggs": {
"brandAgg": {
"terms": {
"field": "brand",
"size": 20
}
}
}
}
修改排序规则(_count):
默认是降序,可以加一个order排序规则
GET /hotel/_search
{
"size":0,
"aggs":{
"brandAgg":{
"terms": {
"field": "brand",
"size": 10,
"order": {
"_count": "asc"
}
}
}
}
}
限定聚合范围
在这里,query的作用范围与aggs聚合同级,作用是限制聚合的文档范围
DSL实现Metrics聚合(嵌套聚合)
记住这里是每个品牌内做统计(要作一个限定)
做一个聚合的嵌套,弄一个brand聚合的子聚合,统计分组后对每组的一个统计
我们还可以再加一个打分的排序,对scoreAgg中的avg进行一个降序排序
#嵌套聚合
GET /hotel/_search
{
"size": 0,
"aggs": {
"brandAgg": {
"terms": {
"field": "brand",
"size": 10,
"order": {
"scoreAgg.avg": "desc"
}
},
"aggs": {
"scoreAgg": {
"stats": {
"field": "score"
}
}
}
}
}
}
RestClient实现聚合(以酒店品牌为例)
结果响应
因为aggs聚合里面有一些限制条件:1.terms类型以及聚合名字 2.字段名 3.size
/**
* 聚合测试
*/
@Test
void testAggreation() throws IOException {
//1.准备request
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
request.source().size(0);
//2.1聚合
request.source().aggregation(AggregationBuilders
.terms("brandAgg")
.field("brand")
.size(10));
//3.发出请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
/**
* 解析响应
*/
Aggregations aggregations = response.getAggregations();
//4.1根据聚合名称得到具体那个类型聚合
Terms brandTerms = aggregations.get("brandAgg");
//4.2然后得到buckets中的数据
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
//4.3进行遍历,得到每一条数据
for (Terms.Bucket bucket : buckets) {
//4.4获取key
String key = bucket.getKeyAsString();
System.out.println(key);
}
}
实现对酒店品牌、城市、星级的过滤
因为我们的酒店过滤不能是静态的,应该是你数据中有什么类型的酒店(杭州、上海...),就展示能够选择什么类型的;
并且我们返回数据应该是map类型:
对接前端接口,将数据显示上去
流程
1.得到request对象后,先设置size
2.然后进行多字段过滤(包括:酒店名称,地区,星级,以及广告打分)
3.聚合:对城市。品牌、星级进行分组
4.发送请求
5.对响应response进行解析,根据聚合名称得到里面的数据文章来源:https://www.toymoban.com/news/detail-408762.html
/**
* 实现字段的聚合过滤
* @return
*/
@Override
public Map<String, List<String>> filters(RequestParams params) throws IOException {
SearchRequest request = new SearchRequest("hotel");
/**
* 准备DSL语句
*/
/*1.设置size*/
request.source().size(0);
extracted(params,request);
/*2.聚合:城市,品牌,星级进行分组*/
request.source().aggregation(AggregationBuilders
.terms("brandAgg")
.field("brand")
.size(100));
request.source().aggregation(AggregationBuilders
.terms("cityAgg")
.field("city")
.size(100));
request.source().aggregation(AggregationBuilders
.terms("starAgg")
.field("starName")
.size(100));
/*3.发出请求,得到响应*/
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
/**
* 4.对响应进行解析
*/
HashMap<String, List<String>> map = new HashMap<>();
Aggregations aggregations = response.getAggregations();
/*4.1根据聚合名称得到品牌数据*/
ArrayList<String> brandList = getStrings(aggregations,"brandAgg");
/*4.2将聚合后的数据放入map中*/
map.put("Brand",brandList);
ArrayList<String> cityList = getStrings(aggregations, "cityAgg");
map.put("City",cityList);
ArrayList<String> starList = getStrings(aggregations, "starAgg");
map.put("StarName",brandList);
return map;
}
/**
* 辅助方法:根据聚合名称得到属于该聚合的所有数据
* @param aggregations
* @return
*/
private ArrayList<String> getStrings(Aggregations aggregations,String name) {
/*得到其中一种聚合*/
Terms brandTerms = aggregations.get(name);
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
/*专门存放key*/
ArrayList<String> list = new ArrayList<>();
for (Terms.Bucket bucket : buckets) {
String key = bucket.getKeyAsString();
list.add(key);
}
return list;
}
多字段过滤(包括:城市、品牌、酒店星级以及广告算分控制)文章来源地址https://www.toymoban.com/news/detail-408762.html
/**
* 辅助
*
* @param params
*/
private void extracted(RequestParams params, SearchRequest request) {
/**
* 辅助字段查询:城市、品牌、酒店星级
*/
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
/*关键字搜索*/
if ((params.getKey()) == null || "".equals(params.getKey())) {
boolQuery.must(QueryBuilders.matchAllQuery());
} else {
boolQuery.must(QueryBuilders.matchQuery("name", params.getKey()));
}
/*城市条件*/
if (params.getCity() != null && !params.getCity().equals("")) {
boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
}
/*品牌条件*/
if (params.getBrand() != null && !params.getBrand().equals("")) {
boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
}
/*星级条件*/
if (params.getStarName() != null && !params.getStarName().equals("")) {
boolQuery.filter(QueryBuilders.termQuery("startName", params.getStarName()));
}
/*价格*/
if (params.getMiniPrice() != null && params.getMaxPrice() != null) {
boolQuery.filter(QueryBuilders
.rangeQuery("price")
.gte(params.getMiniPrice()).lte(params.getMaxPrice()));
}
/**
* 算分控制
*/
FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
//1.基本查询:前面条件查询的内容进行重新打分
boolQuery,
//2.打分数组
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
//3.其中一个打分
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
//过滤条件
QueryBuilders.termQuery("isAD", true),
// 算分函数
ScoreFunctionBuilders.weightFactorFunction(5)
)
}
);
request.source().query(functionScoreQueryBuilder);
}
到了这里,关于elasticsearch-数据聚合的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!