7. elasticsearch聚合

本文介绍了Elasticsearch中的聚合指标,如value_count、cardinality、avg、sum、max、min、percentiles和top_hits,以及date_histogram和histogram的使用。通过实例展示了如何查询特定时间段内的用户唯一访问数(UV)、每日UV,以及商品访问的UV和PV排名。此外,详细解释了date_histogram的时间间隔表达式和histogram的直方图聚合。

ES聚合指标

value_count: 计数 cardinality: 去重计数 avg: 平均值 sum: 求和 max: 最大值 min: 最小值 percentiles: 百分比 top_hits: 简单来说就是聚合分组后从每一个组取部分数据作为结果返回

histogram:直方图集合 date_histogram:日期间隔集合

1, 基础数据 用户登陆信息 包含登陆时间、用户ID等信息

查询某个时间段内uv DSL如下:

{ "query": { "bool": { "filter": [ { "range": { "time": { "gte": "2019-09-02 00:00:00", "lt": "2019-09-09 00:00:00", "format": "yyyy-MM-dd HH:mm:ss", "time_zone": "+08:00" } } } ] } }, "aggs": { "userCount": { "cardinality": { "field": "userId.keyword" } } } }

查询某段时间内每天的uv

{ "query": { "bool": { "filter": [ { "range": { "time": { "gte": "2019-09-02 00:00:00", "lt": "2019-09-09 00:00:00", "format": "yyyy-MM-dd HH:mm:ss", "time_zone": "+08:00" } } } ] } }, "aggs": { "groupBy": { "date_histogram": { "field": "time", "interval": "day" //按天 比如按照7天: 7d, 按照月: month等 }, "aggs": { "userCount": { "cardinality": { "field": "userId.keyword" } } } } } }

2, 基础数据 用户访问商品页信息 包含访问时间、访问商品ID、用户ID等信息

统计一个时间范围内 商品访问uv/pv排行

{ "query": { "bool": { "filter": [ { "range": { "time": { "gte": "2019-07-01 00:00:00", "lt": "2019-09-10 00:00:00", "format": "yyyy-MM-dd HH:mm:ss", "time_zone": "+08:00" } } }, { "terms": { "spuId": [ "224441" //特定spu ] } } ], "must_not": { "match": { "userId.keyword": "" } } } }, "aggs": { "groupBy": { "terms": { "field": "spuId.keyword", "order": { "uv": "desc" //按uv排序,此处也可以修改为按pv排序 } }, "aggs": { "uv": { "cardinality": { //uv userId去重后计数 "field": "userId.keyword" } }, "pv": { "value_count": { //pv userId计数 "field": "userId.keyword" } } } } } }

3. date_histogram 函数的使用

interval(时间间隔)的可用表达式:

  • year(1y)年
  • quarter(1q)季度
  • month(1M)月份
  • week(1w)星期
  • day(1d)天
  • hour(1h)小时
  • minute(1m)分钟
  • second(1s)秒

// 查询

"query": {

"bool": {

"must": [{

"range": {

"@timestamp": {

"gte": 1533556800000,

"lte": 1533806520000

}

}

}]

}

},

// 不显示具体的内容

"size": 0,

// 聚合

"aggs": {

// 自己取的聚合名字

"group_by_grabTime": {

// es提供的时间处理函数

"date_histogram": {

// 需要聚合分组的字段名称, 类型需要为date, 格式没有要求

"field": "@timestamp",

// 按什么时间段聚合, 这里是5分钟, 可用的interval在上面给出

"interval": "5m",

// 设置时区, 这样就相当于东八区的时间

"time_zone":"+08:00",

// 返回值格式化,HH大写,不然不能区分上午、下午

"format": "yyyy-MM-dd HH",

// 为空的话则填充0

"min_doc_count": 0,

// 需要填充0的范围

"extended_bounds": {

"min": 1533556800000,

"max": 1533806520000

}

},

// 聚合

"aggs": {

// 自己取的名称

"group_by_status": {

// es提供

"terms": {

// 聚合字段名

"field": "LowStatusOfPrice"

}

}

}

}

}

5. histogram 直方图聚合

直方图聚合是一个用于评估数值型或是数值范围型价值的文档的多桶(multi-bucket)聚合,它可以对参与聚合的值动态生成固定尺寸的桶。比如,如果一些文档具有数值型字段“price”,我们可以配置聚合间隔为5(在价钱中可能为5元)来动态生成直方图统计。当聚合执行的时候,每个文档的price字段会参与估算,并且为四舍五入到最近的桶中。比如,如果一个文档的price字段值为32,桶的尺寸为5,并且字段值四舍五入后的值为30,那么这个文档就会归入跟30这个关键字关联的桶内。下面的算式可以精确的确定每个文档的归属桶(根据桶的关键字确定)。

bucket_key = Math.floor((value - offset) / interval) * interval + offset

1

注意:interval必须是是一个十进制的正数,同时offset必须是[0,interval)(一个大于等于0、小于interval的十进制数)之间的一个十进制的数。

搜索:

POST /sales/_search?size=0

{

"aggs" : {

"prices" : {

"histogram" : {

"field" : "price",

"interval" : 50

}

}

}

}

结果:

{

...

"aggregations": {

"prices" : {

"buckets": [

{

"key": 0.0,

"doc_count": 1

},

{

"key": 50.0,

"doc_count": 1

},

{

"key": 100.0,

"doc_count": 0

},

{

"key": 150.0,

"doc_count": 2

},

{

"key": 200.0,

"doc_count": 3

}

]

}

}

}

co.elastic.clients.elasticsearch.core.aggregations 是 Java 客户端 ElasticSearch 的一个聚合(Aggregation)方法,用于对数据进行分析和统计。 具体使用方法可以参考以下示例: ```java import co.elastic.clients.base.*; import co.elastic.clients.elasticsearch.*; import co.elastic.clients.elasticsearch.core.*; import co.elastic.clients.elasticsearch.core.aggregations.*; import co.elastic.clients.elasticsearch.core.aggregations.bucket.*; import co.elastic.clients.elasticsearch.core.aggregations.metrics.*; import java.io.IOException; import java.util.*; public class ElasticSearchAggregationExample { public static void main(String[] args) throws IOException, ApiException { RestClientBuilder restClientBuilder = RestClient.builder( new HttpHost("localhost", 9200, "http") ); ElasticSearch client = new ElasticSearch(restClientBuilder); SearchRequest request = new SearchRequest() .index("my_index") .source(new SearchSource() .query(new MatchAllQuery()) .aggregations(new TermsAggregation("my_terms_agg") .field("my_field") .size(10) .subAggregations(new AvgAggregation("my_avg_agg") .field("my_other_field") ) ) ); SearchResponse response = client.search(request); TermsAggregationResult myTermsAggResult = response.aggregations().terms("my_terms_agg"); for (TermsAggregationEntry entry : myTermsAggResult.buckets()) { String term = entry.keyAsString(); long count = entry.docCount(); AvgAggregationResult myAvgAggResult = entry.aggregations().avg("my_avg_agg"); double avg = myAvgAggResult.value(); System.out.println(term + ": " + count + ", avg: " + avg); } client.close(); } } ``` 这个例子展示了如何使用 co.elastic.clients.elasticsearch.core.aggregations 方法来进行聚合查询。在这个例子中,我们使用了 TermsAggregation 和 AvgAggregation 两个聚合方法,对数据进行了分组和统计。具体步骤为: 1. 创建一个 SearchRequest 对象,并设置索引名称和查询条件。 2. 在查询条件中添加聚合条件。这里使用了 TermsAggregation 来对数据进行分组,然后使用 AvgAggregation 来统计每个分组的平均值。 3. 执行查询,并获取查询结果。 4. 使用聚合结果对象的方法来获取聚合结果,然后对结果进行处理。 需要注意的是,聚合方法的具体参数和用法可以参考 ElasticSearch 官方文档。同时,Java 客户端的版本和 ElasticSearch 的版本也需要匹配,否则可能会出现兼容性问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值