zoukankan      html  css  js  c++  java
  • Elasticsearch学习之深入聚合分析二---案例实战

      以一个家电卖场中的电视销售数据为背景,来对各种品牌,各种颜色的电视的销量和销售额,进行各种各样角度的分析,首先建立电视销售的索引,然后

    添加几条销售记录

    PUT /tvs
    {
        "mappings": {
            "sales": {
                "properties": {
                    "price": {
                        "type": "long"
                    },
                    "color": {
                        "type": "keyword"
                    },
                    "brand": {
                        "type": "keyword"
                    },
                    "sold_date": {
                        "type": "date"
                    }
                }
            }
        }
    }
    
    POST /tvs/sales/_bulk
    { "index": {}}
    { "price" : 1000, "color" : "红色", "brand" : "长虹", "sold_date" : "2016-10-28" }
    { "index": {}}
    { "price" : 2000, "color" : "红色", "brand" : "长虹", "sold_date" : "2016-11-05" }
    { "index": {}}
    { "price" : 3000, "color" : "绿色", "brand" : "小米", "sold_date" : "2016-05-18" }
    { "index": {}}
    { "price" : 1500, "color" : "蓝色", "brand" : "TCL", "sold_date" : "2016-07-02" }
    { "index": {}}
    { "price" : 1200, "color" : "绿色", "brand" : "TCL", "sold_date" : "2016-08-19" }
    { "index": {}}
    { "price" : 2000, "color" : "红色", "brand" : "长虹", "sold_date" : "2016-11-05" }
    { "index": {}}
    { "price" : 8000, "color" : "红色", "brand" : "三星", "sold_date" : "2017-01-01" }
    { "index": {}}
    { "price" : 2500, "color" : "蓝色", "brand" : "小米", "sold_date" : "2017-02-12" }
    建立索引及增添数据

    1. 统计哪种颜色的电视销量最高

    GET /tvs/sales/_search
    {
        "size" : 0,
        "aggs" : { 
            "popular_colors" : { 
                "terms" : { 
                  "field" : "color"
                }
            }
        }
    }

    size:只获取聚合结果,而不要执行聚合的原始数据
    aggs:固定语法,要对一份数据执行分组聚合操作
    popular_colors:就是对每个aggs,都要起一个名字,这个名字是随机的,你随便取什么都ok
    terms:根据字段的值进行分组
    field:根据指定的字段的值进行分组

    2. 统计每种颜色电视的平均价格

    GET /tvs/sales/_search
    {
       "size" : 0,
       "aggs": {
          "colors": {
             "terms": {
                "field": "color"
             },
             "aggs": { 
                "avg_price": { 
                   "avg": {
                      "field": "price" 
                   }
                }
             }
          }
       }
    }

      按照color去分bucket,可以拿到每个color bucket中的数量,这个仅仅只是一个bucket操作,doc_count其实只是es的bucket操作默认执行的一个内置metric,除了bucket操作,分组,还要对每个bucket执行一个metric聚合统计操作,在一个aggs执行的bucket操作(terms),平级的json结构下,再加一个aggs,这个第二个aggs内部,同样取个名字,执行一个metric操作,avg,对之前的每个bucket中的数据的指定的field,price field,求一个平均值

    3. 颜色加品牌多层下钻分析

      从颜色到品牌进行下钻分析,每种颜色的平均价格,以及找到每种颜色每个品牌的平均价格,下钻的意思是,已经分了一个组了,比如说颜色的分组,然后还要继续对这个分组内的数据,再分组,比如一个颜色内,还可以分成多个不同的品牌的组,最后对每个最小粒度的分组执行聚合分析操作,这就叫做下钻分析

      es,下钻分析,就要对bucket进行多层嵌套,多次分组按照多个维度(颜色+品牌)多层下钻分析,而且学会了每个下钻维度(颜色,颜色+品牌),都可以对每个维度分别执行一次metric聚合操作

    GET /tvs/sales/_search 
    {
      "size": 0,
      "aggs": {
        "group_by_color": {
          "terms": {
            "field": "color"
          },
          "aggs": {
            "color_avg_price": {
              "avg": {
                "field": "price"
              }
            },
            "group_by_brand": {
              "terms": {
                "field": "brand"
              },
              "aggs": {
                "brand_avg_price": {
                  "avg": {
                    "field": "price"
                  }
                }
              }
            }
          }
        }
      }
    }

    其他metric,例如 count,avg

    count:bucket,terms,自动就会有一个doc_count,就相当于是count
    avg:avg aggs,求平均值
    max:求一个bucket内,指定field值最大的那个数据
    min:求一个bucket内,指定field值最小的那个数据
    sum:求一个bucket内,指定field值的总和

    一般来说,90%的常见的数据分析的操作,metric,无非就是count,avg,max,min,sum

    GET /tvs/sales/_search
    {
       "size" : 0,
       "aggs": {
          "colors": {
             "terms": {
                "field": "color"
             },
             "aggs": {
                "avg_price": { "avg": { "field": "price" } },
                "min_price" : { "min": { "field": "price"} }, 
                "max_price" : { "max": { "field": "price"} },
                "sum_price" : { "sum": { "field": "price" } } 
             }
          }
       }
    }

    4. histogram:类似于terms,也是进行bucket分组操作,接收一个field,按照这个field的值的各个范围区间,进行bucket分组操作

    "histogram":{
    "field": "price",
    "interval": 2000
    },

    interval:2000,划分范围,0~2000,2000~4000,4000~6000,6000~8000,8000~10000,buckets

    去根据price的值,比如2500,看落在哪个区间内,比如2000~4000,此时就会将这条数据放入2000~4000对应的那个bucket中

    bucket划分的方法,terms,将field值相同的数据划分到一个bucket中

    bucket有了之后,同样可以对每个bucket执行avg,count,sum,max,min,等各种metric操作,聚合分析

    示例;按照价格区间统计销售额和电视销量

    GET /tvs/sales/_search
    {
       "size" : 0,
       "aggs":{
          "price":{
             "histogram":{ 
                "field": "price",
                "interval": 2000
             },
             "aggs":{
                "revenue": {
                   "sum": { 
                     "field" : "price"
                   }
                 }
             }
          }
       }
    }

    bucket,分组操作,histogram,按照某个值指定的interval,划分一个一个的bucket

    date histogram,按照我们指定的某个date类型的日期field,以及日期interval,按照一定的日期间隔,去划分bucket

    date interval = 1m,

    2017-01-01~2017-01-31,就是一个bucket
    2017-02-01~2017-02-28,就是一个bucket

    然后会去扫描每个数据的date field,判断date落在哪个bucket中,就将其放入那个bucket

    2017-01-05,就将其放入2017-01-01~2017-01-31,就是一个bucket

    min_doc_count:即使某个日期interval,2017-01-01~2017-01-31中,一条数据都没有,那么这个区间也是要返回的,不然默认是会过滤掉这个区间的
    extended_bounds,min,max:划分bucket的时候,会限定在这个起始日期,和截止日期内

    GET /tvs/sales/_search
    {
       "size" : 0,
       "aggs": {
          "sales": {
             "date_histogram": {
                "field": "sold_date",
                "interval": "month", 
                "format": "yyyy-MM-dd",
                "min_doc_count" : 0, 
                "extended_bounds" : { 
                    "min" : "2016-01-01",
                    "max" : "2017-12-31"
                }
             }
          }
       }
    }

    示例:统计每个季度每个品牌的销售额

    GET /tvs/sales/_search 
    {
      "size": 0,
      "aggs": {
        "group_by_sold_date": {
          "date_histogram": {
            "field": "sold_date",
            "interval": "quarter",
            "format": "yyyy-MM-dd",
            "min_doc_count": 0,
            "extended_bounds": {
              "min": "2016-01-01",
              "max": "2017-12-31"
            }
          },
          "aggs": {
            "group_by_brand": {
              "terms": {
                "field": "brand"
              },
              "aggs": {
                "sum_price": {
                  "sum": {
                    "field": "price"
                  }
                }
              }
            },
            "total_sum_price": {
              "sum": {
                "field": "price"
              }
            }
          }
        }
      }
    }
  • 相关阅读:
    Hadoop命令手册
    编程算法
    综合8种子排序算法总结和比较
    android 创建一个新的每次project什么时候 请问自己主动 参加 V7依赖?
    【JDBC】java PreparedStatement操作oracle数据库
    【cocos2dx 加载资源目录】
    Project Euler:Problem 39 Integer right triangles
    矿Java开发学习之旅------>Java排序算法经典的二分法插入排序
    [React Intl] Render Content with Placeholders using react-intl FormattedMessage
    [React Intl] Install and Configure the Entry Point of react-intl
  • 原文地址:https://www.cnblogs.com/sunfie/p/7101420.html
Copyright © 2011-2022 走看看