如何在Elasticsearch多字段上实现工作日嵌套数据聚合
解决方案
一、基于现有映射的聚合方案
当前映射中workingDays为嵌套字段,且每个日期(mon/tue等)又是独立的嵌套子字段,这种结构下可以通过**脚本化指标聚合(scripted_metric)**直接生成你需要的结果格式:
{ "size": 0, "aggs": { "available_days": { "scripted_metric": { "init_script": "state.days = [:]", "map_script": """ def workingDays = params._source.workingDays; if (workingDays == null) return; // 遍历所有日期字段(根据实际情况补充完整日期) def days = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']; for (def day : days) { def dayData = workingDays[day]; if (dayData != null && dayData.availability == true) { def title = dayData.title; if (title != null) { state.days[title] = (state.days[title] ?: 0) + 1; } } } """, "combine_script": "return state.days", "reduce_script": """ def result = [:]; states.each { bucket -> bucket.each { entry -> result[entry.key] = (result[entry.key] ?: 0) + entry.value; } } // 转换为目标格式 def buckets = []; result.each { k, v -> buckets.add(['key': k, 'doc_count': v]); } return ['buckets': buckets]; """ } } } }
说明:
- 该聚合会遍历每个文档的
workingDays字段,检查每个日期的availability是否为true,收集对应的title并统计出现次数 - 最终结果会直接返回你需要的
buckets数组结构
二、优化映射后的更优方案
现有映射设计不利于聚合操作(每个日期作为独立嵌套字段,需逐个处理),建议将workingDays修改为数组型嵌套字段,映射调整如下:
"workingDays": { "type": "nested", "properties": { "dayOfWeek": { "type": "keyword" }, "availability": { "type": "boolean" }, "title": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }, "notes": { "type": "text" } } }
对应的文档结构改为:
"workingDays": [ { "dayOfWeek": "mon", "availability": true, "title": "Monday", "notes": "" }, { "dayOfWeek": "tue", "availability": false, "title": "Tuesday", "notes": "On Tuesdays, drop off and pick up times must be scheduled between 12pm to 2pm" } ]
此时只需简单的嵌套聚合即可得到目标结果:
{ "size": 0, "aggs": { "working_days_nested": { "nested": { "path": "workingDays" }, "aggs": { "filter_available": { "filter": { "term": { "workingDays.availability": true } }, "aggs": { "day_title_count": { "terms": { "field": "workingDays.title.keyword" } } } } } } } }
结果直接从working_days_nested.filter_available.day_title_count.buckets获取,完全符合你需要的格式。
内容的提问来源于stack exchange,提问作者Nuthan Gowda
相关产品推荐
相关产品推荐

