引言
Bucket aggregations本文译为桶聚合 桶聚合(bucket aggregation)不像指标聚合(Metric aggregation)那样计算字段的指标,而是创建文档存储桶。 每个存储桶都与一个标准(取决于聚合类型)相关联,该标准确定当前上下文中的文档是否“落入”其中。 换句话说,存储桶有效地定义了文档集。 除了存储桶本身之外,存储桶聚合还计算并返回落入每个存储桶的文档数量。
1.Terms Aggregation
术语聚合(Terms Aggregation)在文档的指定字段中搜索唯一值,并为找到的每个唯一值构建存储桶。 给出一个稍微复杂的例子:获取每个每个国家中每个省份的平均年龄
GET users/_search
{
"size": 0,
"aggs": {
"countries": {
"terms": {
"field": "country"
},
"aggs": {
"provinces": {
"terms": {
"field": "province"
},
"aggs": {
"average_age": {
"avg": {
"field": "age"
}
}
}
}
}
}
}
}
响应结果:
"aggregations" : {
"countries" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "cn",
"doc_count" : 3,
"countries" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "zhejiang",
"doc_count" : 2,
"average_age" : {
"value" : 32.0
}
},
{
"key" : "shanghai",
"doc_count" : 1,
"average_age" : {
"value" : 30.0
}
}
]
}
},
{
"key" : "us",
"doc_count" : 3,
"countries" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "newyork",
"doc_count" : 2,
"average_age" : {
"value" : 33.0
}
},
{
"key" : "pennsylvania",
"doc_count" : 1,
"average_age" : {
"value" : 44.0
}
}
]
}
}
]
}
从结果可以看到terms agg返回是各个buckets ,每个bucket 都有对应的key 和属于该桶的文档数doc_count 。默认情况下,响应将返回10个桶。当然也可以指定size参数改变返回的桶的数量。 下面说下对应的参数含义和用途
- size:size 参数指定返回的桶的数量,默认值10。当
size 的值小于对应field 真实个数时,返回的doc_count 可能不是精确的。
官方给出了详细的例子,总结就是,因为每个shard节点都有返回最合适size个结果,然后基于每个shard节点的结果,给出最终合适的size结果给客户端,这就存在误差,比如某个term在其中一个节点的文档数小于top size的排序,则这个节点的term的文档数,不会返回作为最终结果的一部分,导致数据不准确。
- shard_size:上面讲到size的大小可能影响数据的精确,当我们每次查询都把size设置超大的时候是可以保证数据的精确,但是代价也是很大的,因为每个shard节点都要获取size大小返回到客户端,最终得到最优的结果,(特殊是数据规模较大的数据)导致es内部网络开销比较大,而且shard节点返回的大部分数据都是无用的。所以就有了shard_size可以控制每个shard节点返回对应的size的大小。默认情况下,
shard_size 的大小为 (size * 1.5 + 10) - sum_other_doc_count:表示不在
size 分桶中文档个数。 - doc_count_error_upper_bound:这个值表示的是在聚合中,没有在最终结果中的term最大可能有doc_count_error_upper_bound个文档。这是ES预估可能出现的最坏的结果,它的计算公式是每个shard节点最后一个term文档数之和(例如size是10,就是取每个shard排序第10个term文档数之和)
- show_term_doc_count_error:显示每个分桶可能错误的上限。是个
boolean 值,默认是false ,需改为true ,才会显示。它的计算方式是:响应结果中的term ,把没有返回该term 的shard节点,最后一个term文档数加起来之和。(例如响应结果中有anhui ,但是其中有一个shard节点,该anhui term并没有在前size 中,那么该值就是第size 的term 文档数)。 - order:聚合结果按照指定域排序。默认情况下,是按照
doc_count 降序排序的。返回对应size 个分桶。
举几个例子
按照文档数升序
"order" : { "_count" : "asc" }
按照term字符串升序
"order" : { "_term" : "asc" }
还可以按照子聚合的参数进行排序,建议到官网查看。
- min_doc_count:限制响应结果的最小文档数,如果桶中文档数小于指定的文档数,将不会响应给客户端,默认值1。
- include,exclude:根据业务只展示有需要的term。
{
"aggs" : {
"tags" : {
"terms" : {
"field" : "tags",
"include" : ".*sport.*",
"exclude" : "water_.*"
}
}
}
}
{
"aggs" : {
"JapaneseCars" : {
"terms" : {
"field" : "make",
"include" : ["mazda", "honda"]
}
},
"ActiveCarManufacturers" : {
"terms" : {
"field" : "make",
"exclude" : ["rover", "jensen"]
}
}
}
}
- 分组:当响应返回大量的桶时,我们可以把这些桶进行分组,然后分组处理。
{
"size": 0,
"aggs": {
"expired_sessions": {
"terms": {
"field": "account_id",
"include": {
"partition": 0,
"num_partitions": 20
},
"size": 10000,
"order": {
"_term": "asc"
}
}
}
}
}
例如上面的分组,account_id 存在大量的不同值,所以采用分组返回,分组字段为:num_partitions , 获取对应分组的数据为partition ,范围为[0-num_partitions-1] ,每个分组的大小为:size
分组内的排序不是全局排序,只是当前分组内数据的排序。
|