如何在Elasticsearch中按日期聚合并展示visible的两种状态
实现按日期+Visible状态分组的聚合查询
嗨,我来帮你搞定这个需求!你想要的是每个日期分别展示visible字段的true和false两种状态(即使其中一种状态没有数据也要显示),只需要调整一下Elasticsearch聚合的嵌套顺序,再用R语言把结果整理成表格就行。
修改后的Elasticsearch查询
核心思路是先按日期分组,再在每个日期组内按visible状态分组,这样就能得到每个日期下两种状态的计数。另外要配置参数确保空状态也能返回:
{ "query":{ "bool":{ "must":[ { "match":{ "merchant":"a6xzTHtpQs" } }, { "range":{ "time":{ "gte":"2018-04-02T06:00:00", "lte":"2018-04-03T05:59:59", "time_zone":"+00:00" } } ] } }, "aggs":{ "daily":{ "date_histogram":{ "field":"time", "interval":"day", // 改成按天聚合,匹配你的日期需求 "time_zone":"+00:00", "min_doc_count":0, // 确保没有数据的日期也返回 "extended_bounds":{ "min":"2018-04-02T06:00:00", "max":"2018-04-03T05:59:59" } }, "aggs":{ "Visible_agg":{ "terms":{ "field":"visible", "size":2, // 强制返回true/false两个选项 "min_doc_count":0 // 即使某个状态无数据也返回计数0 } } } } } }
用R的elastic包处理结果
发送查询后,需要逐层提取聚合结果,转换成你要的表格格式:
library(elastic) # 假设你已经通过connect()建立了ES连接,赋值给conn对象 # 替换成你的索引名称 index_name <- "your_elasticsearch_index" # 定义查询语句 agg_query <- '{ "query":{ "bool":{ "must":[ { "match":{ "merchant":"a6xzTHtpQs" } }, { "range":{ "time":{ "gte":"2018-04-02T06:00:00", "lte":"2018-04-03T05:59:59", "time_zone":"+00:00" } } ] } }, "aggs":{ "daily":{ "date_histogram":{ "field":"time", "interval":"day", "time_zone":"+00:00", "min_doc_count":0, "extended_bounds":{ "min":"2018-04-02T06:00:00", "max":"2018-04-03T05:59:59" } }, "aggs":{ "Visible_agg":{ "terms":{ "field":"visible", "size":2, "min_doc_count":0 } } } } } }' # 发送查询 search_result <- search(conn, body = agg_query, index = index_name) # 提取聚合数据并整理成数据框 daily_buckets <- search_result$aggregations$daily$buckets final_df <- data.frame(date = character(), visible = logical(), count = integer(), stringsAsFactors = FALSE) for (day_bucket in daily_buckets) { # 将ES返回的时间戳转换为YYYY-MM-DD格式的日期字符串 date_val <- as.POSIXct(day_bucket$key / 1000, origin = "1970-01-01", tz = "UTC") date_str <- format(date_val, "%Y-%m-%d") # 遍历每个visible状态的子桶 for (vis_bucket in day_bucket$Visible_agg$buckets) { final_df <- rbind(final_df, data.frame( date = date_str, visible = as.logical(vis_bucket$key), count = vis_bucket$doc_count, stringsAsFactors = FALSE )) } } # 查看最终结果 print(final_df)
注意事项
- 确保你的
visible字段是Elasticsearch中的布尔类型,如果是字符串类型(比如"true"/"false"),需要把R代码里的as.logical(vis_bucket$key)改成as.character(vis_bucket$key)或者对应处理。 - 如果需要按小时聚合,只需要把
interval改回"hour"即可,其他逻辑不变。
内容的提问来源于stack exchange,提问作者Mus
相关产品推荐
相关产品推荐

