本节 es 笔记目录如下:

  1. 分组计数
  2. 平均数 avg
  3. 最大值 max
  4. 最小值 min
  5. 总和 sum

此次笔记用到的数据还是前一节中导入的官方提供的 bank 数据,用到其他数据的,下面会提供导入方式。

首先,来看一下我们导入的数据的各个字段,使用下面命令获取(命令都在 kibana 中使用):

"_source" : {
    "account_number" : 1,
    "balance" : 39225,
    "firstname" : "Amber",
    "lastname" : "Duke",
    "age" : 32,
    "gender" : "M",
    "address" : "880 Holmes Lane",
    "employer" : "Pyrami",
    "email" : "amberduke@pyrami.com",
    "city" : "Brogan",
    "state" : "IL"
  }

1、分组计数

我们对数据中 state 字段进行分组计数,计算数据中每个 state 种类出现的次数:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

其中, group_by_state 是分组的名称,用来标识分组的名称,
terms 则是用来分组的关键字,
state.keyword 表示取值是 state 这个字段。

运行之后返回,可以看到返回结果按照 state 的值,作为 key,以及 doc_count 作为 count 的数值结果返回。

对应于 MySQL 中的语法大致是:

SELECT state, COUNT(*) FROM table_name GROUP BY state;

限定分组返回的数据结果:
使用到上一节笔记中的 fromsize

在上面的语法中在 aggssize 字段,是用来限定返回结果中的源数据的条数,赋值为 0 表示不返回源数据。

而要限制分类结果的 size(默认十条),则是在 terms 下一级,与 field同级。

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "size": 30
      }
    }
  }
}

2、平均数 avg

我们想知道 bank 这个 index 下的所有数据中 age字段的平均值,也就是所有人的平均年龄,语法如下:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "average_of_age": {
      "avg": {
        "field": "age"
      }
    }
  }
}

主体返回结果如下:

"aggregations" : {
    "average_of_age" : {
      "value" : 30.171
    }
  }

average_of_agevalue 值就是我们要的 年龄平均值了。

这个语法在 MySQL 中对应如下:

SELECT AVG(age) FROM table_name;

missing 值的使用:
在 es 里面,还有个 missing 关键字,这个字是干啥的呢?
当我们不能保证所有的数据都是完整的,尤其是涉及到查询的字段,就需要用到 missing 这个词。

作用是缺失值替代,也就是加了这个关键字,并且带上参数以后,在查询计算中如果查询的字段值缺失,那么就会默认使用到 missing 这个词。

bank 的数据太多了,我们可以手动创建几条数据测试:

PUT /exam/_doc/1
{
    "name" : "hunter",
    "grade": 60
}
PUT /exam/_doc/2
{
    "name" : "paul",
    "grade": 80
}
PUT /exam/_doc/3
{
    "name" : "jack",
    "grade": 90
}
PUT /exam/_doc/4
{
    "name" : "tom",
}

可以通过如下语句看一下这几条数据:

GET /exam/_search
{
  "query": {
    "match_all": {}
  }
}

可以看到,最后一条数据是没有 grade 这个字段的,

当我们直接求取平均值:

GET /exam/_search
{
  "size": 0,
  "aggs": {
    "avg_of_grade": {
      "avg": {
        "field": "grade"
      }
    }
  }
}

可以看到返回结果:

"aggregations" : {
    "avg_of_grade" : {
      "value" : 76.66666666666667
    }
  }

可以得出这个结果是只获取了有 grade 字段的三条数据,然后进行平均值计算。
当我们加上 missing 关键字:

GET /exam/_search
{
  "size": 0,
  "aggs": {
    "avg_of_grade": {
      "avg": {
        "field": "grade",
        "missing": 60
      }
    }
  }
}

返回结果如下:

"aggregations" : {
    "avg_of_grade" : {
      "value" : 72.5
    }
  }

可以知道虽然第四条没有 grade 的数据,但是通过 missing 指定默认值,得出了计算结果。

以上就是 missing 的用法。

3、最大值 max

max 的用法和 avg 的使用方法一样,语法如下:

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

返回结果:

"aggregations" : {
    "max_age" : {
      "value" : 40.0
    }
  }

使用 script 方法计算数据:
我们还可以使用 script 的方式来得出计算结果:

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

还有一种对返回的结果进行计算的脚本方式:

GET /bank/_search
{
  "size": 0,
  "aggs":{
    "max_age": {
      "max": {
        "field": "age",
        "script": {
          "source": "_value * params.conversion_rate",
          "params": {
            "conversion_rate": 1.2
          }
        }
      }
    }
  }
}

4、最小值 min

最小值的计算方法和最大值相同,关键字 max 改成 min即可,如下是示例:

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

如上语法对应 MySQL 中的是:

SELECT MIN(age) FROM table_name;

5、计算总和 sum

目标:计算数据中 age 的总和

GET /bank/_search
{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggs": {
    "sum_age": {
      "sum": {
        "field": "age"
      }
    }
  }
}

对应于 MySQL 中的语法是:

SELECT SUM(age) FROM table_name;

如果要加上筛选条件,比如 state 的值为 TX 的数据的 age 的总和:

GET /bank/_search
{
  "size": 0,
  "query": {
    "match": {
      "state": "TX"
    }
  },
  "aggs": {
    "sum_age": {
      "sum": {
        "field": "age"
      }
    }
  }
}

对应于 MySQL 中的语法是:

SELECT SUM(age) FROM table_name WHERE age='TX';