前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Elasticsearch系列十二】聚合-电视案例

【Elasticsearch系列十二】聚合-电视案例

原创
作者头像
kwan的解忧杂货铺
发布2024-09-18 19:44:30
710
发布2024-09-18 19:44:30

创建索引及映射

代码语言:apl
复制
PUT /tvs
PUT /tvs/_search
{
			"properties": {
				"price": {
					"type": "long"
				},
				"color": {
					"type": "keyword"
				},
				"brand": {
					"type": "keyword"
				},
				"sold_date": {
					"type": "date"
				}
			}
}

插入数据

代码语言:apl
复制
POST /tvs/_bulk
{ "index": {}}
{ "price" : 1000, "color" : "红色", "brand" : "长虹", "sold_date" : "2019-10-28" }
{ "index": {}}
{ "price" : 2000, "color" : "红色", "brand" : "长虹", "sold_date" : "2019-11-05" }
{ "index": {}}
{ "price" : 3000, "color" : "绿色", "brand" : "小米", "sold_date" : "2019-05-18" }
{ "index": {}}
{ "price" : 1500, "color" : "蓝色", "brand" : "TCL", "sold_date" : "2019-07-02" }
{ "index": {}}
{ "price" : 1200, "color" : "绿色", "brand" : "TCL", "sold_date" : "2019-08-19" }
{ "index": {}}
{ "price" : 2000, "color" : "红色", "brand" : "长虹", "sold_date" : "2019-11-05" }
{ "index": {}}
{ "price" : 8000, "color" : "红色", "brand" : "三星", "sold_date" : "2020-01-01" }
{ "index": {}}
{ "price" : 2500, "color" : "蓝色", "brand" : "小米", "sold_date" : "2020-02-12" }

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

代码语言:apl
复制
GET /tvs/_search
{
    "size" : 0,
    "aggs" : {
        "popular_colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}

查询条件解析

size:只获取聚合结果,而不要执行聚合的原始数据

aggs:固定语法,要对一份数据执行分组聚合操作

popular_colors:就是对每个 aggs,都要起一个名字,

terms:根据字段的值进行分组

field:根据指定的字段的值进行分组

返回

代码语言:apl
复制
{
  "took" : 18,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "popular_colors" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "红色",
          "doc_count" : 4
        },
        {
          "key" : "绿色",
          "doc_count" : 2
        },
        {
          "key" : "蓝色",
          "doc_count" : 2
        }
      ]
    }
  }
}

返回结果解析

hits.hits:我们指定了 size 是 0,所以 hits.hits 就是空的

aggregations:聚合结果

popular_color:我们指定的某个聚合的名称

buckets:根据我们指定的 field 划分出的 buckets

key:每个 bucket 对应的那个值

doc_count:这个 bucket 分组内,有多少个数据

数量,其实就是这种颜色的销量

每种颜色对应的 bucket 中的数据的默认的排序规则:按照 doc_count 降序排序

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

代码语言:apl
复制
GET /tvs/_search
{
   "size" : 0,
   "aggs": {
      "colors": {
         "terms": {
            "field": "color"
         },
         "aggs": {
            "avg_price": {
               "avg": {
                  "field": "price"
               }
            }
         }
      }
   }
}

在一个 aggs 执行的 bucket 操作(terms),平级的 json 结构下,再加一个 aggs,这个第二个 aggs 内部,同样取个名字,执行一个 metric 操作,avg,对之前的每个 bucket 中的数据的指定的 field,price field,求一个平均值

返回:

代码语言:json
复制
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 8,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "colors": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "红色",
          "doc_count": 4,
          "avg_price": {
            "value": 3250.0
          }
        },
        {
          "key": "绿色",
          "doc_count": 2,
          "avg_price": {
            "value": 2100.0
          }
        },
        {
          "key": "蓝色",
          "doc_count": 2,
          "avg_price": {
            "value": 2000.0
          }
        }
      ]
    }
  }
}

buckets,除了 key 和 doc_count

avg_price:我们自己取的 metric aggs 的名字

value:我们的 metric 计算的结果,每个 bucket 中的数据的 price 字段求平均值后的结果

相当于 sql: select avg(price) from tvs group by color

3.继续下钻分析

每个颜色下,平均价格及每个颜色下,每个品牌的平均价格

代码语言:apl
复制
GET /tvs/_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"
              }
            }
          }
        }
      }
    }
  }
}

4.更多的 metric

count:bucket,terms,自动就会有一个 doc_count,就相当于是 count

avg:avg aggs,求平均值

max:求一个 bucket 内,指定 field 值最大的那个数据

min:求一个 bucket 内,指定 field 值最小的那个数据

sum:求一个 bucket 内,指定 field 值的总和

代码语言:apl
复制
GET /tvs/_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" } }
         }
      }
   }
}

5.划分范围 histogram

代码语言:apl
复制
GET /tvs/_search
{
   "size" : 0,
   "aggs":{
      "price":{
         "histogram":{
            "field": "price",
            "interval": 2000
         },
         "aggs":{
            "income": {
               "sum": {
                 "field" : "price"
               }
             }
         }
      }
   }
}

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

代码语言:apl
复制
"histogram":{
  "field": "price",
  "interval": 2000
}

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

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

6.按照日期分组聚合

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

min_doc_count:即使某个日期 interval,2017-01-01~2017-01-31 中,一条数据都没有,那么这个区间也是要返回的,不然默认是会过滤掉这个区间的

extended_bounds,min,max:划分 bucket 的时候,会限定在这个起始日期,和截止日期内

代码语言:apl
复制
GET /tvs/_search
{
   "size" : 0,
   "aggs": {
      "sales": {
         "date_histogram": {
            "field": "sold_date",
            "interval": "month",
            "format": "yyyy-MM-dd",
            "min_doc_count" : 0,
            "extended_bounds" : {
                "min" : "2019-01-01",
                "max" : "2020-12-31"
            }
         }
      }
   }
}

7.统计每季度每个品牌的销售额

代码语言:apl
复制
GET /tvs/_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": "2019-01-01",
          "max": "2020-12-31"
        }
      },
      "aggs": {
        "group_by_brand": {
          "terms": {
            "field": "brand"
          },
          "aggs": {
            "sum_price": {
              "sum": {
                "field": "price"
              }
            }
          }
        },
        "total_sum_price": {
          "sum": {
            "field": "price"
          }
        }
      }
    }
  }
}

8.搜索与聚合结合,查询某个品牌按颜色销量

搜索与聚合可以结合起来。

sql select count(*)

from tvs

where brand like "%小米%"

group by color

es aggregation,scope,任何的聚合,都必须在搜索出来的结果数据中之行,搜索结果,就是聚合分析操作的 scope

代码语言:apl
复制
GET /tvs/_search
{
  "size": 0,
  "query": {
    "term": {
      "brand": {
        "value": "小米"
      }
    }
  },
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color"
      }
    }
  }
}

9.global bucket:单个品牌与所有品牌销量对比

aggregation,scope,一个聚合操作,必须在 query 的搜索结果范围内执行

出来两个结果,一个结果,是基于 query 搜索结果来聚合的; 一个结果,是对所有数据执行聚合的

代码语言:apl
复制
GET /tvs/_search
{
  "size": 0,
  "query": {
    "term": {
      "brand": {
        "value": "小米"
      }
    }
  },
  "aggs": {
    "single_brand_avg_price": {
      "avg": {
        "field": "price"
      }
    },
    "all": {
      "global": {},
      "aggs": {
        "all_brand_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

10.过滤+聚合:统计价格大于 1200 的电视平均价格

搜索+聚合

过滤+聚合

代码语言:apl
复制
GET /tvs/_search
{
  "size": 0,
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "price": {
            "gte": 1200
          }
        }
      }
    }
  },
  "aggs": {
    "avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

11.bucket filter:统计品牌最近一个月的平均价格

代码语言:apl
复制
GET /tvs/_search
{
  "size": 0,
  "query": {
    "term": {
      "brand": {
        "value": "小米"
      }
    }
  },
  "aggs": {
    "recent_150d": {
      "filter": {
        "range": {
          "sold_date": {
            "gte": "now-150d"
          }
        }
      },
      "aggs": {
        "recent_150d_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "recent_140d": {
      "filter": {
        "range": {
          "sold_date": {
            "gte": "now-140d"
          }
        }
      },
      "aggs": {
        "recent_140d_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "recent_130d": {
      "filter": {
        "range": {
          "sold_date": {
            "gte": "now-130d"
          }
        }
      },
      "aggs": {
        "recent_130d_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

aggs.filter,针对的是聚合去做的

如果放 query 里面的 filter,是全局的,会对所有的数据都有影响

但是,如果,比如说,你要统计,长虹电视,最近 1 个月的平均值; 最近 3 个月的平均值; 最近 6 个月的平均值

bucket filter:对不同的 bucket 下的 aggs,进行 filter

12.按每种颜色的平均销售额降序排序

代码语言:apl
复制
GET /tvs/_search
{
  "size": 0,
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color",
        "order": {
          "avg_price": "asc"
        }
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

相当于 sql 子表数据字段可以立刻使用。

13.排序:按每种颜色的每种品牌平均销售额降序排序

代码语言:apl
复制
GET /tvs/_search
{
  "size": 0,
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "group_by_brand": {
          "terms": {
            "field": "brand",
            "order": {
              "avg_price": "desc"
            }
          },
          "aggs": {
            "avg_price": {
              "avg": {
                "field": "price"
              }
            }
          }
        }
      }
    }
  }
}

Elasticsearch 的主要优点包括:

  1. 分布式设计:Elasticsearch 天然支持分布式,可以很容易地横向扩容,处理 PB 级结构化或非结构化数据。
  2. 高效的搜索能力:Elasticsearch 提供了全文搜索功能,支持模糊查询、前缀查询、通配符查询等,并且具有强大的聚合分析功能。
  3. 快速的查询速度:Elasticsearch 的底层使用 Lucene 作为搜索引擎,并在此之上做了多重优化,保证了用户对数据查询的需求。
  4. 易用性:Elasticsearch 提供了简单的 RESTful API,天生的兼容多语言开发,上手容易,开箱即用。
  5. 丰富的生态圈:Elasticsearch 有丰富的插件和工具,如 Logstash、Kibana、Beats 等,形成了强大的 Elastic Stack 生态。

Elasticsearch 的使用场景包括:

  1. 应用搜索:为网站或应用程序提供搜索功能,如电商、社交媒体等。
  2. 日志记录和日志分析:收集、存储和分析服务器日志、应用日志等。
  3. 基础设施监控:监控服务器、网络设备等基础设施的性能指标。
  4. 安全分析:分析安全日志,进行入侵检测和威胁分析。
  5. 地理位置数据分析:处理地理空间数据,提供地理位置搜索服务。
  6. 商业智能:对商业数据进行分析,提供决策支持。

Elasticsearch 的引入主要是为了应对大数据环境下的海量数据检索和实时分析需求,它通过分布式架构和高效的索引机制,提供了快速的搜索和分析能力。然而,Elasticsearch 也存在一些潜在风险,如响应时间问题和任务恢复延迟等,需要通过优化配置和维护来降低这些风险的影响。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.统计哪种颜色的电视销量最高
  • 2,统计每种颜色电视平均价格
  • 3.继续下钻分析
  • 4.更多的 metric
  • 5.划分范围 histogram
    • 6.按照日期分组聚合
    • 7.统计每季度每个品牌的销售额
    • 8.搜索与聚合结合,查询某个品牌按颜色销量
    • 9.global bucket:单个品牌与所有品牌销量对比
    • 10.过滤+聚合:统计价格大于 1200 的电视平均价格
    • 11.bucket filter:统计品牌最近一个月的平均价格
    • 12.按每种颜色的平均销售额降序排序
    • 13.排序:按每种颜色的每种品牌平均销售额降序排序
    相关产品与服务
    云服务器
    云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档