欢迎光临
我们一直在努力

Springcloud篇9-Elasticsearch-3(数据聚合、自动补全、数据同步、集群)

一、数据聚合

1.1 聚合的分类

聚合可以实现对文档数据的统计、分析、运算(MySQL中的聚合函数有avg,max,min,sum,一般还要结合group by 分组使用)。常见的有三类: (1)桶(Bucket)聚合:用来对文档做分组。 TermAggregation:按文档字段值(该字段不能分词,不能是text)分组 Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组 (2)度量(Metric)聚合:用以计算一些值,比如最大值、最小值、平均值 Avg:求平均值 Max:求最大值 Min:求最小值 Stats:同时求max、min、avg、sum等。 (3)管道(pipeline)聚合:其它聚合的结果为基础做聚合

1.2 DSL实现

还是博文springcloud篇7中添加的hotel索引:

# 酒店的mapping
PUT /hotel
{


\”mappings\”:{


\”properties\”:{


\”id\”:{


\”type\”:\”keyword\”
},
\”name\”:{


\”type\”:\”text\”,
\”analyzer\”:\”ik_max_word\”,
\”copy_to\”:\”all\”
},
\”address\”:{


\”type\”:\”keyword\”,
\”index\”:false
},
\”price\”:{


\”type\”:\”integer\”
},
\”score\”:{


\”type\”:\”integer\”
},
\”brand\”:{


\”type\”:\”keyword\”,
\”copy_to\”:\”all\”
},
\”city\”:{


\”type\”:\”keyword\”
},
\”starName\”:{


\”type\”:\”keyword\”
},
\”business\”:{


\”type\”:\”keyword\”,
\”copy_to\”:\”all\”
},
\”location\”:{


\”type\”:\”geo_point\”
},
\”pic\”:{


\”type\”:\”keyword\”,
\”index\”:false
},
\”all\”:{


\”type\”:\”text\”,
\”analyzer\”:\”ik_max_word\”
}
}
}
}

1.2.1 实现Bucket聚合

例子:统计所有数据中的酒店品牌有几种,此时可以根据酒店品牌的名称做聚合。 在这里插入图片描述 在这里插入图片描述

在这里插入图片描述

# 聚合功能
GET /hotel/_search
{


\”size\”:0,
\”aggs\”:{


\”brandAgg\”:{


\”terms\”:{


\”field\”:\”brand\”,
\”size\”:10
}
}
}
}

补充1.Bucket聚合-聚合结果排序

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为_count,并且按照_count降序排序。 可以修改结果排序方式: 在这里插入图片描述 在这里插入图片描述

# 聚合功能,自定义排序规则
GET /hotel/_search
{


\”size\”:0,
\”aggs\”:{


\”brandAgg\”:{


\”terms\”:{


\”field\”:\”brand\”,
\”size\”:20,
\”order\”:{


\”_count\”:\”asc\”
}
}
}
}
}

补充2.Bucket聚合-限定聚合范围

默认情况下,Bucket聚合是对索引库的所有文档做聚合,可以限定要聚合的文档范围,只要添加query条件即可。 在这里插入图片描述 在这里插入图片描述

# 聚合功能,限定聚合范围
GET /hotel/_search
{


\”query\”:{


\”range\”:{


\”price\”:{


\”lte\”:200
}
}
},
\”size\”:0,
\”aggs\”:{


\”brandAgg\”:{


\”terms\”:{


\”field\”:\”brand\”,
\”size\”:20,
\”order\”:{


\”_count\”:\”asc\”
}
}
}
}
}

1.2.2 实现Metric聚合

需与bucket聚合结合使用。 例子,获取每个品牌的用户评分的min、max、avg等值。 在这里插入图片描述 从上图中可以看出,聚合可以嵌套,brandAgg聚合内部嵌套了一个score_stats聚合。 在这里插入图片描述

# 嵌套聚合metric
GET /hotel/_search
{


\”size\”:0,
\”aggs\”:{


\”brandAgg\”:{


\”terms\”:{


\”field\”:\”brand\”,
\”size\”:20
},
\”aggs\”:{


\”scoreAgg\”:{


\”stats\”:{


\”field\”:\”score\”
}
}
}
}
}
}

再根据聚合的计算结果排序: 在这里插入图片描述

# 嵌套聚合metric
GET /hotel/_search
{


\”size\”:0,
\”aggs\”:{


\”brandAgg\”:{


\”terms\”:{


\”field\”:\”brand\”,
\”size\”:20,
\”order\”:{


\”scoreAgg.avg\”:\”desc\”
}
},
\”aggs\”:{


\”scoreAgg\”:{


\”stats\”:{


\”field\”:\”score\”
}
}
}
}
}
}

1.3 RestAPI实现聚合

获取查询结果: 在这里插入图片描述 聚合结果解析: 在这里插入图片描述 在这里插入图片描述

@Test
void testAggregation() throws IOException {


//1.创建Request对象
SearchRequest request=new SearchRequest(\”hotel\”);
//2.准备DSL语句
//2.1 设置size
request.source().size(0);
//2.2 聚合
request.source().aggregation(AggregationBuilders.terms(\”brandAgg\”).field(\”brand\”).size(10));
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println(response);
//4.解析结果
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){


String key = bucket.getKeyAsString();
System.out.println(key);
}
}

在这里插入图片描述

1.4 多条件聚合

在这里插入图片描述 如上图所示,前端页面的筛选条件(城市、星级、品牌和价格)的选项并不是前端写死的,而是要通过后台搜索聚合结果得到。 在这里插入图片描述

public interface IHotelService extends IService<Hotel> {


PageResult search(RequestParams params);
Map<String, List<String>> filters();
}

在这里插入图片描述

@Override
public Map<String, List<String>> filters() {


try {


//1.创建Request对象
SearchRequest request=new SearchRequest(\”hotel\”);
//2.准备DSL语句
//2.1 设置size
request.source().size(0);
//2.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.解析结果
Map<String, List<String>> result = new HashMap<>();
Aggregations aggregations = response.getAggregations();
List<String> brandList = getAggByName(aggregations,\”brandAgg\”);
result.put(\”品牌\”, brandList);
List<String> cityList = getAggByName(aggregations,\”cityAgg\”);
result.put(\”城市\”, cityList);
List<String> starList = getAggByName(aggregations,\”starAgg\”);
result.put(\”星级\”, starList);
return result;
} catch (IOException e) {


throw new RuntimeException(e);
}
}

private static List<String> getAggByName(Aggregations aggregations,String aggName) {


//4.1根据聚合名称获取聚合结果
Terms brandTerms = aggregations.get(aggName);
//4.2 获取buckets
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
//4.3 遍历
List<String> brandList = new ArrayList<>();
for(Terms.Bucket bucket : buckets

赞(0)
未经允许不得转载:171主机测评 » Springcloud篇9-Elasticsearch-3(数据聚合、自动补全、数据同步、集群)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址