6 Elasticsearch聚合分析

上一次聊了5 Elasticsearch深入搜索,这次来看看聚合。API链接为: https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-nested-query.html 。

聚合说明

什么是聚合?Kibana上的这些图就是聚合,底层通过ES能够实现。

在这里插入图片描述

ES支持哪些聚合?聚合有很多类型,主要看Metrics和Bucket

在这里插入图片描述

  • Bucket Aggregation:一些列满足特定条件的文档的集合
  • Metric Aggregation:一些数学运算,可以对文档字段进行统计分析
  • Pipeline Aggreagtion:对其它的聚合结果进行二次聚合
  • Matrix Aggregation:支持对多个字段的操作并提供一个结果矩阵

Bucket和Metric如果用MySQL类比

在这里插入图片描述

聚合API

Aggregation属于Search的一部分,语法如下

在这里插入图片描述

Metric

说明
  1. Metric会基于数据集计算结果,除了支持在字段上进行计算,同时也支持在脚本(painless script)产生的结果之上进行计算
  2. 大多数Metric是数学计算,仅输出一个值,如min/max/sum/avg/cardinality
  3. 部分metric支持输出多个数值,如stats/percentiles/percentile_ranks

在这里插入图片描述

实战

查询电影中,最大的一年

在这里插入图片描述

如果size大于1,会返回对应的条目信息

在这里插入图片描述

Bucket

说明
  1. 按照⼀定的规则,将⽂档分配到不同的桶中,从⽽达到分类的⽬的。类似于MySQL的group。
  2. ⽀持嵌套:也就在桶⾥再做分桶。⼦聚合分析可以是Bucket和Metric
  3. Term Aggregations对于text字段,需要打开fielddata才可以使用

在这里插入图片描述

实战

按照年group

在这里插入图片描述

设置返回数量

在这里插入图片描述

先按年group,然后按年内的类型group

在这里插入图片描述

聚合执行过程

聚合其实是从各个分片获取数据,然后进行组合的过程,Min和Term的聚合过程如下

在这里插入图片描述

在这里插入图片描述

通过Terms的样例,能够发现聚合的结果未必是准确的,因为数据是分散的,每个Node的top3未必是全局的top3。ES提供了一些参数可以用来解决或者优化这个问题。

关联查询

Joining queries为”关联查询” 或 “连接查询”。这种查询方式主要用于在 Elasticsearch 中处理具有层次结构的数据,例如,一个博客文章(父文档)和它的评论(子文档)。通过使用has_childhas_parentparent_id等查询类型,可以实现对这类数据的有效检索。

在这里插入图片描述

Nested(嵌套)场景

“nested”(嵌套)是一种数据类型和查询方式,用于处理复杂的数据结构。具体来说,它允许你在文档中存储数组类型的对象,并且这些对象中的每个元素都可以被单独索引和查询。

假设写了一个电影的mapping

PUT my_movies
{
      "mappings" : {
      "properties" : {
        "actors" : {
          "properties" : {
            "first_name" : {
              "type" : "keyword"
            },
            "last_name" : {
              "type" : "keyword"
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
}

写入一条电影doc

POST my_movies/_doc/1
{
  "title":"Speed",
  "actors":[
    {
      "first_name":"Keanu",
      "last_name":"Reeves"
    },

    {
      "first_name":"Dennis",
      "last_name":"Hopper"
    }

  ]
}

进行查询

POST my_movies/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"actors.first_name": "Keanu"}},
        {"match": {"actors.last_name": "Hopper"}}
      ]
    }
  }
}

发现竟然能够查到结果:

在这里插入图片描述

这是因为ES存储时,内部对象的边界并没有考虑在内,JSON 格式被处理成扁平式键值对的结构

在这里插入图片描述

为了解决这个问题,我们使用Nested。创建 Nested 对象 Mapping,即增加type为nested

PUT my_movies
{
      "mappings" : {
      "properties" : {
        "actors" : {
          "type": "nested",
          "properties" : {
            "first_name" : {"type" : "keyword"},
            "last_name" : {"type" : "keyword"}
          }},
        "title" : {
          "type" : "text",
          "fields" : {"keyword":{"type":"keyword","ignore_above":256}}
        }
      }
    }
}

重新插入数据,使用nested进行查询发现查不到了,如果使用正确的first_name和last_name可以查到

POST my_movies/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"title": "Speed"}},
        {
          "nested": {
            "path": "actors",
            "query": {
              "bool": {
                "must": [
                  {"match": {
                    "actors.first_name": "Keanu"
                  }},

                  {"match": {
                    "actors.last_name": "Hopper"
                  }}
                ]
              }
            }
          }
        }
      ]
    }
  }
}

在这里插入图片描述

在这里插入图片描述

这是因为在ES内部, Nested ⽂档会被保存在两个 Lucene⽂档中,会在查询时做 Join 处理

在这里插入图片描述

Nested(嵌套)聚合

我们可以在Nested上做聚合

POST my_movies/_search
{
  "size": 0,
  "aggs": {
    "actors": {
      "nested": {
        "path": "actors"
      },
      "aggs": {
        "actor_name": {
          "terms": {
            "field": "actors.first_name",
            "size": 10
          }
        }
      }
    }
  }
}

在这里插入图片描述

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

  1. 设计模式

  2. 招聘

  3. 思考

  4. 存储

  5. 算法系列

  6. 读书笔记

  7. 小工具

  8. 架构

  9. 网络

  10. Go语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员麻辣烫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值