说明
本文描述问题及解决方法同样适用于 腾讯云 Elasticsearch Service(ES)。
背景
参数:extended_bounds
该参数用来限制数据的范围,因为ES默认统计field最大值和最小值之间的所有数据。
问题
ES查询直方图数据,结果明显发生了越界:
代码语言:json复制GET robot_msg_202012/_search
{
"size":0,
"query":{
"bool":{
"must":[
{
"term":{
"kfuin":{
"value":"2852199391"
}
}
},
{
"term":{
"robot_id":{
"value":"921678007"
}
}
},
{
"range":{
"msg_time":{
"gte":1607529600000000,
"lte":1608134399000000
}
}
}
]
}
},
"aggs":{
"time_range_aggs":{
"histogram":{
"field":"msg_time",
"interval":86400000000,
"min_doc_count":0,
"extended_bounds":{
"min":1607529600000000,
"max":1608134399000000
}
},
"aggs":{
"single_wheel_message_match_nums_sub_aggs":{
"filter":{
"bool":{
"must":[
{
"term":{
"answer_type":{
"value":1
}
}
},
{
"bool":{
"must_not":{
"term":{
"reply_type":0
}
}
}
}
]
}
},
"aggs":{
"single_wheel_message_match_nums_sub_sub_aggs":{
"value_count":{
"field":"msg_time"
}
}
}
},
"message_match_total_nums_sub_aggs":{
"value_count":{
"field":"msg_time"
}
},
"multi_wheel_dos_sent_message_nums_sub_aggs":{
"value_count":{
"field":"dos_sent"
}
},
"multi_wheel_unsat_eval_message_nums_sub_aggs":{
"value_count":{
"field":"unsat_eval"
}
}
}
}
}
}
图中可以看到查询结果的key低于min。
问题原因
这里的越界其实是符合预期的,因为真正的边界取决于interval,而不是min,所表现出的特征是:
结果中看到的最小key(1607040000000000),可以被interval(864000000000)所整除
当extended_bounds.min不被interval整除的时候,默认的最小值为:
代码语言:javascript复制key = extended_bounds.min - (extended_bounds.min % interval)
解决方法
histogram提供了offset,以偏移桶的边界,其算法是:
代码语言:javascript复制offset = extended_bounds.min % interval
正确的做法是出现这种情况时,设置offset值,这样最小key就会等于extended_bounds.min,问题就会得到解决。
offset原理
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html#_offset_2