Elasticsearch date_histogram聚合无法展示完整时间范围如何解决?
Elasticsearch date_histogram聚合缺失月份问题解决
我使用Elasticsearch的date_histogram聚合查询2021年1月至12月的数据,现有查询语句如下:
{ "from": 0, "size": 0, "query": { "bool": { "must": [ { "term": { "medicalRecordDiagnosesDischarge.catDiseaseGroupDetail.catDiseasesGroup.diseasesGroupId": { "value": 13, "boost": 1 } } }, { "range": { "examinationDate": { "from": "2021-01-01T00:00:00.000Z", "to": "2022-01-01T00:00:00.000Z", "include_lower": true, "include_upper": false, "boost": 1 } } } ] } }, "aggregations": { "agg_name": { "date_histogram": { "field": "examinationDate", "format": "MM", "calendar_interval": "1M", "offset": 0, "order": { "_key": "asc" }, "keyed": false, "min_doc_count": 0 } } } }
但查询结果仅返回1月至8月的桶,缺失9、10、11、12月的数据:
"buckets" : [ { "key_as_string" : "01", "key" : 1609459200000, "doc_count" : 66 }, { "key_as_string" : "02", "key" : 1612137600000, "doc_count" : 18 }, { "key_as_string" : "03", "key" : 1614556800000, "doc_count" : 114 }, { "key_as_string" : "04", "key" : 1617235200000, "doc_count" : 15 }, { "key_as_string" : "05", "key" : 1619827200000, "doc_count" : 22 }, { "key_as_string" : "06", "key" : 1622505600000, "doc_count" : 1 }, { "key_as_string" : "07", "key" : 1625097600000, "doc_count" : 2 }, { "key_as_string" : "08", "key" : 1627776000000, "doc_count" : 3 } ]
期望得到包含全年12个月份的聚合结果:
[ { "key_as_string" : "01", "doc_count": 0 }, { "key_as_string" : "02", "doc_count": 0 }, { "key_as_string" : "03", "doc_count": 0 }, { "key_as_string" : "04", "doc_count": 0 }, { "key_as_string" : "05", "doc_count": 0 }, { "key_as_string" : "06", "doc_count": 0 }, { "key_as_string" : "07", "doc_count": 0 }, { "key_as_string" : "08", "doc_count": 0 }, { "key_as_string" : "09", "doc_count": 0 }, { "key_as_string" : "10", "doc_count": 0 }, { "key_as_string" : "11", "doc_count": 0 }, { "key_as_string" : "12", "doc_count": 0 } ]
曾尝试使用extended_bounds但出现重复结果,以下是正确的解决方法:
解决方案
要强制生成指定时间范围内的所有月份桶,需在date_histogram聚合中同时配置min_doc_count: 0和extended_bounds,并确保extended_bounds的范围与查询的时间范围完全匹配:
修改后的聚合部分如下:
"aggregations": { "agg_name": { "date_histogram": { "field": "examinationDate", "format": "MM", "calendar_interval": "1M", "offset": 0, "order": { "_key": "asc" }, "keyed": false, "min_doc_count": 0, "extended_bounds": { "min": "2021-01-01T00:00:00.000Z", "max": "2021-12-31T23:59:59.999Z" } } } }
关键说明:
min_doc_count: 0:确保即使某月份没有匹配数据,也会生成对应的空桶(doc_count: 0)。extended_bounds:强制ES生成min到max范围内的所有时间桶,不受查询结果中实际存在的数据限制。这里将max设为2021年12月最后一刻,避免包含2022年1月的桶。- 范围匹配:
extended_bounds的时间范围需与查询语句中range的范围对齐,防止生成超出目标时间范围的桶,这也是之前出现重复结果的常见原因。
此方案同样适用于calendar_interval设为季度的场景,只需调整extended_bounds和calendar_interval参数即可。
内容的提问来源于stack exchange,提问作者Tho Ho Xuan
相关产品推荐
相关产品推荐

