关于后端:es笔记六之聚合操作之指标聚合

64次阅读

共计 5262 个字符,预计需要花费 14 分钟才能阅读完成。

本文首发于公众号:Hunter 后端
原文链接:es 笔记六之聚合操作之指标聚合

聚合操作,在 es 中的聚合能够分为大略四种聚合:

  • bucketing(桶聚合)
  • mertic(指标聚合)
  • matrix(矩阵聚合)
  • pipeline(管道聚合)

bucket
相似于分类分组,依照某个 key 将符合条件的数据都放到该类别的组中

mertic
计算一组文档的相干值,比方最大,最小值

matrix
依据多个 key 从文档中提取值生成矩阵,这个操作不反对脚本(script)

pipeline
将其余聚合的后果再次聚合输入

聚合是反对套娃(嵌套)操作的,你能够在聚合的后果上接着进行聚合操作,es 是不限度聚合的深度的。

本篇笔记目录如下:

  1. 指标聚合的根本构造
  2. 平均值聚合
  3. 去重统计
  4. 聚合统计汇总
  5. 最大值、最小值聚合
  6. 百分位统计
  7. 百分位排名
  8. 字符串统计聚合
  9. sum 统计总和操作
  10. count 统计总数操作
  11. top hit 操作

1、指标聚合的根本构造

指标聚合操作的根本构造大抵如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "aggregation_name": {
      "agg_name": {"field": "field_name"}
    }
  }
}

其中,aggregation_name 为聚合返回后果的名称,由咱们本人定义,agg_name 为聚合的参数,比方最大值最小值,平均值等,这个咱们在上面介绍。

指标聚合

指标聚合是从文档中提取字段值进去进行计算得出后果,比方最大最小平均值等。

接下来将具体介绍各种指标聚合操作。

2、平均值聚合

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "avg_balance": {
      "avg": {"field": "balance"}
    }
  }
}

其中,最外层的 aggs 示意是聚合操作,avg_balance 是聚合的名称,avg 则示意是平均值聚合,外面的 field 示意聚合的字段是 balance 字段

在这里,如果不增加 size=0,除了会返回咱们的聚合后果,还会返回聚合的源数据。

这个操作咱们返回的后果如下:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1000,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : []},
  "aggregations" : {
    "avg_balance" : {"value" : 25714.837}
  }
}

咱们聚合的后果在 aggregations 这个 key 下。

脚本执行

脚本执行的形式如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "avg_balance": {
      "avg": {"script": {"source": "doc.balance.value"}
      }
    }
  }
}

对后果解决

假如,咱们须要对这个平均值后果进行解决,比方咱们计算出来的这个值是 2000,咱们想要对这个值进行修改,比方乘以 1.2。

当然,这个乘的操作咱们能够获取数据之后在零碎里进行操作,如果是间接在 es 的解决中,咱们能够如下实现:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "avg_corrected_balance": {
      "avg": {
        "field": "balance", 
        "script": {
          "lang": "painless",
          "source": "_value * params.correction",
          "params": {"correction": 1.2}
          
        }
      }
    },
    "avg_balance": {
      "avg": {"script": {"source": "doc.balance.value"}
      }
    }
  }
}

在下面的语句中,咱们新增了一个 params 字段,定义了一个 correction 的值,而后返回的后果乘以了这个值。

在这里,我额定加了一个 avg_balance,是间接用的平均值聚合后果,次要是用来比照这两个后果。

缺失值补充

有一些状况,咱们在导入数据的时候,可能某条数据的某个字段是没有值的,默认状况下他们是会被疏忽的,不计入计算的,然而如果想要为其加一个默认值也是能够实现的,这里咱们用到 missing 这个参数来定义:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "avg_balance": {
      "avg": {
        "field": "balance",
        "missing": 0
      }
    }
  }
}

3、去重统计

是对某个字段进行去重后统计总数,操作如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_count": {
      "cardinality": {"field": "age"}
    }
  }
}

须要留神的是,这个统计对于 text 字段属性是不失效的

4、聚合统计汇总

有一个聚合统计汇总的参数 stats,能够将个别的聚合值进行汇总后返回,比方总数,最大值,最小值等,应用如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_stats": {
      "stats": {"field": "age"}
    }
  }
}

能够看到返回的值如下:

{
 ...
 "aggregations" : {
    "age_stats" : {
      "count" : 1000,
      "min" : 20.0,
      "max" : 40.0,
      "avg" : 30.171,
      "sum" : 30171.0
    }
  }
}

如果还想取得方差,标准差等数据,能够应用这个参数的扩大版 extended_stats,替换聚合的参数 stats 即可。

5、最大值、最小值聚合

最大值最小值的关键字是 max 和 min,应用示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "max_age": {"max": {"field": "age"}
    },
    "min_age": {"min": {"field": "age"}
    }
  }
}

应用脚本的形式来实现:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "max_age": {"max": {"script": {"source": "doc.age.value"}}
    }
  }
}

6、百分位统计

应用 es 进行百分位的统计,用到的关键字是 percentiles

应用示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_percentiles": {
      "percentiles": {"field": "age"}
    }
  }
}

会输入 [1, 5, 25, 75, 95, 99] 的统计数:

{
  ...
  "aggregations" : {
    "age_percentiles" : {
      "values" : {
        "1.0" : 20.0,
        "5.0" : 21.0,
        "25.0" : 25.0,
        "50.0" : 30.8,
        "75.0" : 35.0,
        "95.0" : 39.0,
        "99.0" : 40.0
      }
    }
  }
}

咱们也能够指定统计的百分位的数列表,比方咱们只想晓得 [75, 98, 99, 99.9] 的数据:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_percentiles": {
      "percentiles": {
        "field": "age",
        "percents": [75, 98, 99, 99.9]
      }
    }
  }
}

咱们间接应用是返回的百分位 - 数据的格局,咱们也能够应用 {‘key’: xx, ‘value’: xx} 来返回一个列表,加上一个参数 keyed=false 即可

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_percentiles": {
      "percentiles": {
        "field": "age",
        "keyed": false
      }
    }
  }
}

返回的后果示例如下:

    "age_percentiles" : {
      "values" : [
         ...
        {
          "key" : 75.0,
          "value" : 35.0
        },
        {
          "key" : 95.0,
          "value" : 39.0
        },
        {
          "key" : 99.0,
          "value" : 40.0
        }
      ]
    }
  }
}

7、百分位排名

这个是和后面的百分位统计相同的操作。

后面是依据百分位获取该百分位值,这个参数的作用是依据数据获取在零碎中的百分位,应用示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_ranks": {
      "percentile_ranks": {
        "field": "age",
        "values": [
          30,
          35,
          40
        ]
      }
    }
  }
}

8、字符串统计聚合

对于字符串类型的数据,有一个专门的参数来获取相应的聚合统计值,为 string_stats

对 lastname 字段的统计示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "last_name_stats": {"string_stats": {"field": "lastname.keyword"}
    }
  }
}

须要留神,如果咱们须要进行统计的字段如果是 text 字段,那么就须要加上 .keyword 来进行统计,如果是字段属性是 keyword,就不须要这样解决。

通过统计返回的数据如下:

  ... 
  "aggregations" : {
    "last_name_stats" : {
      "count" : 1000,
      "min_length" : 2,
      "max_length" : 11,
      "avg_length" : 6.122,
      "entropy" : 4.726472133462717
    }
  }
}

以上信息包含数据总数,lastname 字段最长和最短长度,均匀长度和熵值

9、sum 统计总和操作

比方咱们须要对 bank 这个数据库的 age 字段进行 sum 的操作,能够如下操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_sum": {"sum": {"field": "age"}
    }
  }
}

在后面的每一个聚合操作里,都能够进行 query 的条件筛选,比方获取 age=21 的数据的 sum 值:

GET /bank/_search
{
  "size": 0,
  "query": {"match": {"age": "21"}}, 
  "aggs": {
    "age_sum": {"sum": {"field": "age"}
    }
  }
}

10、count 统计总数操作

count 是统计总数,应用示例如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "age_count": {
      "value_count": {"field": "age"}
    }
  }
}

11、top hit 操作

top hit 操作是依据条件返回符合条件的前几条数据,通过 size 管制返回的数量。

咱们先来看下上面的这个操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "top_ages": {
      "terms": {
        "field": "age",
        "size": 30
      }
    }
  }
}

这个操作其实就是一个桶聚合,它会在下一篇笔记中介绍,这里咱们间接用一下,它返回字段为 age,以及它在文档中的数量:

  ...
  "aggregations" : {
    "top_ages" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 31,
          "doc_count" : 61
        },
        {
          "key" : 39,
          "doc_count" : 60
        },
        {
          "key" : 26,
          "doc_count" : 59
        },
        ...

top_hits 的操作是在第一个 aggs 聚合操作条件下,进行再次聚合。

比方咱们想要获取各个 age 的数据中,依照 balance 字段进行倒序排序的前三个,咱们能够如下操作:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "top_ages": {
      "terms": {
        "field": "age",
        "size": 30
      },
      "aggs": {
        "top_balance_hits": {
          "top_hits": {
            "size": 3,
            "sort": [{"balance": {"order": "desc"}}]
          }
        }
      }
    }
  }
}

而后在第一次聚合返回的后果中,就会多一个 top_balance_hits 字段,也就是咱们在查问操作中指定的,其下会有三条依照 balance 字段倒序返回的数据:

  ...
  "aggregations" : {
    "top_ages" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : 31,
          "doc_count" : 61,
          "top_balance_hits" : {
            "hits" : {
              "total" : {
                "value" : 61,
                "relation" : "eq"
              },
              "max_score" : null,
              "hits" : [...]
        },
        {
          "key" : 39,
          "doc_count" : 60,
          ...
        },
        {
          "key" : 26,
          "doc_count" : 59,
          ...
        },
        ...

如果想获取更多后端相干文章,可扫码关注浏览:

正文完
 0