版权声明

本文为Elastic开源社区版权所有,保证独立性和原创性,未获得授权和允许,任何组织和个人不得以任何方式传播或复制或分享,如若转发,请标注原创链接。否则必将追究法律责任。

知识内容输出不易,请尊重他人劳动成果。严禁随意传播、复制和盗用他人成果或文章内容用以商业或盈利目的!

1、概述

1.1 基本概念

在 Elasticsearch 中,聚合查询是一种分析和统计数据的功能。聚合查询能够处理大量的数据,执行各种统计分析,如计算总数、平均值、最大值、最小值、标准差等等,并生成相应的报告。

聚合(aggs)不同于普通查询,是目前学到的第二种大的查询分类,第一种即 query,因此在代码中的第一层嵌套由 query 变为了 aggs 。

1.2 使用场景

聚合查询可以用于各种场景,比如商业智能、数据挖掘、日志分析等等。

  • 电商平台的销售分析:统计每个地区的销售额、每个用户的消费总额、每个产品的销售量等,以便更好地了解销售情况和趋势。
  • 社交媒体的用户行为分析:统计每个用户的发布次数、转发次数、评论次数等,以便更好地了解用户行为和趋势,同时可以将数据按照地区、时间、话题等维度进行分析。
  • 物流企业的运输分析:统计每个区域的运输量、每个车辆的运输次数、每个司机的行驶里程等,以便更好地了解运输情况和优化运输效率。
  • 金融企业的交易分析:统计每个客户的交易总额、每个产品的销售量、每个交易员的业绩等,以便更好地了解交易情况和优化业务流程。
  • 智能家居的设备监控分析:统计每个设备的使用次数、每个家庭的能源消耗量、每个时间段的设备使用率等,以便更好地了解用户需求和优化设备效能。

1.3 基本语法

聚合查询的语法结构与其他查询相似,通常包含以下部分:

  • 查询条件:指定需要聚合的文档,可以使用标准的 Elasticsearch 查询语法,如 term、match、range 等等。
  • 聚合函数:指定要执行的聚合操作,如 sum、avg、min、max、terms、date_histogram 等等。每个聚合命令都会生成一个聚合结果。
  • 聚合嵌套:聚合命令可以嵌套,以便更细粒度地分析数据。
GET <index_name>/_search
{
  "aggs": {
    "<aggs_name>": { // 聚合名称需要自己定义
      "<agg_type>": {
        "field": "<field_name>"
      }
    }
  }
}
  • aggs_name:聚合函数的名称
  • agg_type:聚合种类,比如是桶聚合(terms)或者是指标聚合(avg、sum、min、max等)
  • field_name:字段名称或者叫域名。

2、三种类型的聚合

2.1 桶聚合:Bucket Aggregations

2.1.1 概念

类比 SQL 中的 group by 的作用,主要用于统计不同类型数据的数量。

在 Elasticsearch 中,桶聚合是一种常用的聚合查询操作,它将文档分为多个“桶”,然后在每个桶上进行统计分析。

2.1.2 场景

桶聚合可以用于各种场景,例如:

  • 对数据进行分组统计,比如按照地区、年龄段、性别等字段进行分组统计。

1

  • 对时间序列数据进行时间段分析,比如按照每小时、每天、每月、每季度、每年等时间段进行分析。
  • 对各种标签信息分类,并统计其数量。

2

2.1.3 用法

以 goods 索引为例

GET goods/_search
{
  "aggs": {
    "agg_tag_value_count": {
      "terms": {
        "field": "tags" // 注意如果是文本,请使用 keyword 类型
      }
    }
  }
}

3

GET goods/_search
{
  "aggs": {
    "agg_price_interval": {
      "range": {
        "field": "price",
        "ranges": [
          {
            "to": 1000
          },
          {
            "from": 1000,
            "to": 5000
          },
          {
            "from": 5000
          }
        ]
      }
    }
  }
}

2.1.4 Multi Terms

当在聚合的时候需要对多个字段同时聚合的时候,可以使用 multi_terms 来完成

GET /<index_name>/_search
{
  "aggs": {
    "agg_name": {
      "multi_terms": {
        "terms": [
          {
            "field": "field_1"
          },
          {
            "field": "field_2"
          }
        ]
      }
    }
  }
}

2.2 指标聚合:Metrics Aggregations

2.2.1 场景

用于统计某个指标,如最大值、最小值、平均值,可以结合桶聚合一起使用,如按照商品类型分桶,统计每个桶的平均价格。

4

2.2.2 指标函数

  • 平均值:Avg
  • 最大值:Max
  • 最小值:Min
  • 求和:Sum
  • 详细信息:Stats
  • 数量:Value count

2.2.3 案例

GET goods/_search
{
  "aggs": {
    "max_price": {
      "max": {
        "field": "price"
      }
    },
    "min_price": {
      "min": {
        "field": "price"
      }
    },
    "avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

2.3 管道聚合:Pipeline Aggregations

2.3.1 概念

管道聚合用于对聚合的结果进行二次聚合,如要统计绑定数量最多的标签 bucket,就是要先按照标签进行分桶,再在分桶的结果上计算最大值。

2.3.2 场景:

用于对聚合查询的二次聚合,如统计平均成绩最高的学生,即先按照学生姓名(或 id)进行桶聚合,并计算其平均成绩,然后对其平均成绩计算最大值聚合

5-1686444387291

2.3.3 基本语法

GET <index_name>/_search
{
  "aggs": {
    "my_aggs": {
      "<function>": {
        ...
      },
      "aggs": {
        "my_price_bucket": {
          ...
        }
      }
    },
    "my_min_bucket":{
      "<pip_function>": {
        "buckets_path": "my_aggs>price_bucket"
      }
    }
  }
}

参数

  • buckets_path:路径相对于管道聚合的位置,不是绝对路径,路径不能返回“向上”的路径

2.3.4 函数

  • Min bucket:******
  • Max bucket:******
  • Avg bucket:********
  • Sum bucket:******
  • Stats bucket:******

****:buckets_path ******************,********************************************。**************,my_aggs ** my_min_bucket ****,my_aggs ****buckets_path **********。

3、************

3.1 doc values

doc values ****************************,******************************,****true,**********************************,**************************,********** doc values ****************。

**********,doc values ******************** ******** 。******** **********、****、**********,**********、********、****、IP ********( not_analyzed )********************,****** **text**** **annotated_text******

PUT test_doc_values
{
  "mappings": {
    "properties": {
      "text_field": {
        "type": "text",  // ****************
        "fields": {
          "doc_value_filed1": {
            "type": "keyword",
            "doc_values": true  // ****************
          },
          "doc_value_filed2": {
            "type": "keyword",
            "doc_values": false // ******************
          }
        }
      },
      "doc_value_filed1": {
        "type": "long",
        "doc_values": true // ****************
      },
      "doc_value_filed3": {
        "type": "long",
        "doc_values": false // ****************
      }
    }  
  }
}

3.2 fielddata:

****:******************,********************、**********************,********** fielddata ********,**************************。** doc value ****,******doc value ****************,******** fielddata,****************************,fielddata ****************** JVM Heap **。Fielddata **************,**** text **********,************************,************************************。

****:

PUT /<index>/_mapping
{
  "properties": {
    "tags": {
      "type": "text",
      "fielddata": true  // true:****fielddata;	false:**** fielddata
    }
  }
}

4、********

4.1 ****

GET <index_name>/_search
{
  "aggs": {
    "<agg_name>": {
      "<agg_type>": {
        "field": "<field_name>"
      },
      "aggs": {
        "<agg_name_child>": {
          "<agg_type>": {
            "field": "<field_name>"
          }
        }
      }
    }
  }
}

****:************************************,****************************,****************************,************************

4.2 ****

**** 1:**************************************

GET goods/_search
{
  "size": 0,
  "aggs": {
    "term_brand": {
      "terms": {
        "field": "brand.keyword"
      },
      "aggs": {
        "term_type": {
          "terms": {
            "field": "type.keyword"
          }
        }
      }
    }
  }
}

**** 2:****************************(********、******、********)

GET goods/_search
{
  "size": 0, 
  "aggs": {
    "term_lv": {
      "terms": {
        "field": "lv.keyword"
      },
      "aggs": {
        "agg_price": {
          "stats": {
            "field": "price"
          }
        }
      }
    }
  }
}

4.3 ****

  • ****************************

  • ******************************

  • ****************** multi_terms ******

    • multi_terms:******************
    • ********:****************,****************

5、**********

5.1 **************

  • size:**********************,******** 10,** size: 20,********** 20 ******。

  • order_type:********************,************

    • _count:****************
    • _key:************ key ******
    • _term:7.x ************,**********,ES 8.x ******************。
  • order_value:**************

    • asc:********
    • desc:********
GET <index_name>/_search
{
  "size": 0, // ****************************
  "aggs": {
    "term_lv": {
      "terms": {
        "field": "<doc_value_field>",
        "size": 10, // ************** 10 ******
        "order": {
          "<order_type>": "<order_value>"
        }
      }
    }
  }
}

5.2 **********

****** order by a,b,******** a ********,**************** b ****。

****:

  • ****************
  • **********************************
  • ******************************
GET goods/_search?size=0
{
  "aggs": {
    "first_sort": {
      "terms": {
        "field": "brand.keyword",
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      }
    }
  }
}

5.3 ****************

****:****************,******************************,******************。

GET goods/_search
{
  "size": 0,
  "aggs": {
    "agg_term_brand": {
      "terms": {
        "field": "brand.keyword",
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "agg_term_tags": {
          "terms": {
            "field": "tags.keyword",
            "order": {
              "_count": "desc"
            }
          }
        }
      }
    }
  }
}

6

5.4 ****************

****:**********************************?

GET goods/_search
{
  "size": 0,
  "aggs": {
    "agg_term_tag": {
      "terms": {
        "field": "brand.keyword",
        "order": {
          "agg_stats_price.avg": "asc"
        }
      },
      "aggs": {
        "agg_stats_price": {
          "stats": {
            "field": "price"
          }
        }
      }
    }
  }
}

************,******************,********************************。

8

5.5 ****

** goods ****,************************。

  • **********************
  • ******************************
  • ********************,************************************
GET goods/_search?size=0
{
  "aggs": {
    "terms_tags": {
      "terms": {
        "field": "tags.keyword",
        "order": [
          {
            "_count": "desc" // ********************************
          },
          {
            "stats_price.avg": "desc" // ****************
          }
        ]
      },
      "aggs": {
        "stats_price": {
          "stats": {
            "field": "price"
          }
        }
      }
    }
  }
}

6、******

6.1 Filter

Filter ************************,**************************,********

POST <index_name>/_search
{
  "aggs": {
    "phone_agg": {
      "filter": {
        ...
      },
      "aggs": {
        ...
      }
    }
  }
}

**** 1

******** goods ****,****************************************** phone ****************

POST goods/_search
{
  "size": 0,
  "aggs": {
    "avg_price": { "avg": { "field": "price" } },
    "phone_agg": {
      "filter": { "term": { "type.keyword": "phone" } },
      "aggs": {
        "avg_price": { "avg": { "field": "price" } }
      }
    }
  }
} 

**** 2:

**************************,****************、****、**********************。

GET goods/_search
{
  "size": 0,
  "aggs": {
    "agg_stats": {
      "filter": {
        "terms": {
          "type.keyword": [
            "****",
            "****",
            "****"
          ]
        }
      },
      "aggs": {
        "stats": {
          "stats": {
            "field": "price"
          }
        }
      }
    }
  }
}

6.2 Filters

********************

GET goods/_search
{
  "size": 0,
  "aggs": {
    "types": {
      "filters": {
        "filters": {
          "phone": {
            "term": {
              "type.keyword": "phone"
            }
          },
          "erji": {
            "term": {
              "type.keyword": "erji"
            }
          }
        }
      }
    }
  }
}

**************************** Filter ****,********

GET goods/_search
{
  "size": 0,
  "query": {
    "terms": {
      "type": [
        "phone",
        "erji"
      ]
    }
  },
  "aggs": {
    "phone_agg": {
      "terms": {
        "field": "type.keyword"
      }
    }
  }
}

******************************,************,************************

PUT /logs/_bulk?refresh
{ "index" : { "_id" : 1 } }
{ "body" : "warning: page could not be rendered" }
{ "index" : { "_id" : 2 } }
{ "body" : "authentication error" }
{ "index" : { "_id" : 3 } }
{ "body" : "warning: connection timed out" }

GET logs/_search
{
  "size": 0,
  "aggs" : {
    "messages" : {
      "filters" : {
        "filters" : {
          "errors" :   { "match" : { "body" : "error"   }},
          "warnings" : { "match" : { "body" : "warning" }}
        }
      }
    }
  }
}

6.3 ************

GET <index>/_search
{
  "query": {
    ...
  }, 
  "aggs": {
    ...
  }
}

********,************** query ****************,** query **** aggs ******************。

************ query ** aggs,**************************。query ************、******** filter、**** bool query。

**:************** phone **************************** DSL

POST goods/_search?filter_path=aggregations
{
  "size": 0,
  "query": {
    "term": {
      "type.keyword": "phone"
    }
  },
  "aggs": {
    "avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

6.4 Global

GET goods/_search
{
  "size": 10,
  "query": {
    ...
  },
  "aggs": {
    "avg_price": {
      ...
    },
    "all_avg_price": {
      "global": {},
      "aggs": {
        ...
      }
    }
  }
}

**********,avg_price **************** query ************,** all_avg_price ************ all data **。

****

GET goods/_search
{
  "size": 0,
  "query": {
    "range": {
      "price": {
        "gte": 20000
      }
    }
  },
  "aggs": {
    "avg_price": {
      "avg": {
        "field": "price"
      }
    },
    "all_avg_price": {
      "global": {},
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "muti_avg_price": {
      "filter": {
        "range": {
          "price": {  
            "lte": 20000
          }
        }
      }, 
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

6.5 Post Filter ********

GET product/_search
{
  "aggs": {
    ...
  },
  "post_filter": {
    ...
  }
}

********** post filter ******************。**************************

****:************,******IOS****************。

GET goods/_search
{
  "aggs": {
    "tags_bucket": {
      "terms": {
        "field": "tags.keyword"
      }
    }
  },
  "post_filter": {
    "term": {
      "tags.keyword": "IOS"
    }
  }
}

7、**************:Top Hits

Top hits(********)**************,**************************(bucket)******** N ******。**********************************************************************。

****:********************,********************** 5 ******

GET goods/_search
{
  "size": 0,
  "aggs": {
    "tags_bucket": {
      "terms": {
        "field": "type.keyword"
      },
      "aggs": {
        "top_agg": {
          "top_hits": {
            "size": 10,
            "sort": [
              {
                "price": {
                  "order": "desc"
                }
              }
            ],
            "from": 0
          }
        }
      }
    }
  }
}

8、**************:Bucket Sort

** Elasticsearch **,Bucket Sort **************,********(bucket)********。********************************************,**************************。

Bucket Sort **********:

{
  "aggs": {
    "aggregation_name": {
      "terms": {
        "field": "******"
      },
      "aggs": {
        "sort_field": {
          "bucket_sort": {
            "sort": [
              {
                "******": {
                  "order": "********"
                }
              }
            ]
          }
        }
      }
    }
  }
}

****,“aggregation_name” ****************,“******” ************************。************************************************,** “asc”(****)** “desc”(****)。

**************,****************** “sales” ******,******************,**********************。**********************************,********************** 5 ******。

************ Bucket Sort ******:

{
  "size": 0,
  "aggs": {
    "top_products": {
      "terms": {
        "field": "product_name",
        "size": 5
      },
      "aggs": {
        "sort_sales_amount": {
          "bucket_sort": {
            "sort": [
              {
                "sales_amount": {
                  "order": "desc"
                }
              }
            ],
            "size": 5
          }
        }
      }
    }
  }
}

************,************ “terms” ******** “product_name” ************,****** “size” ** 5,******** 5 ******。****,************,**** “bucket_sort” ************,**** “sales_amount” ********************。****,******** “size” ** 5,****************************** 5 ******。

******** Bucket Sort,**********************************************,****************************。************ N ********************************************。

9、**************

9.1 histogram

****:************,****************************
****:

histogram:******************

GET product/_search?size=0
{
  "aggs": {
    "<histogram_name>": {
      "histogram": {
        "field": "price", 				#********
        "interval": 1000,					#********
        "keyed": true,						#********************
        "min_doc_count": <num>,		#**********************,************num**************
        "missing": 1999						#************,**************************,**********1999(******)
      }
    }
  }
}

9.2 date-histogram

****************,**************************

GET product/_search?size=0
{
  "aggs": {
    "my_date_histogram": {
      "date_histogram": {
        "field": "createtime",					#********date****
        "<interval_type>": "month",			#********************
        "format": "yyyy-MM", 						#****************
        "extended_bounds": {						#********
          "min": "2020-01",
          "max": "2020-12"
        }
      }
    }
  }
}
  • interval_type:********************

    • fixed_interval:ms(****)、s(**)、 m(****)、h(****)、d(**),**************************,**2d******。******************,******************************。
    • calendar_interval:
      • year
      • quarter
      • month
      • week
      • day
      • hour
      • minute
    • ** 8.x ****** interval ******,************** 7.x ******,******************: image**************** 8.x ******,******************。
  • missing:********************,****************。

  • min_doc_count:****************************************************。********0,************************,************。

  • time_zone:************************。**********,Elasticsearch********************。**:"time_zone": "Asia/Shanghai",

  • offset:****************************。**************************************。****,"+1h"******************1****。

  • keyed:**************************************。**********true,************************************,******false。

  • extended_bounds:********************。************"min"**"max"****************************。

9.3 percentile

********************

percentiles:************************,**** 99 percentile ** 1000 , **** 99%********** 1000 ****。************************** SLA ********** 99% **************100ms ****,****************** 99 percentile ********,****** 99 percenttile ********** 100ms ****,****** SLA ******。
****:

GET <index_name>/_search?size=0
{
  "aggs": {
    "<percentiles_name>": {
      "percentiles": {
        "field": "price",
        "percents": [
  				percent1,				#**********,**5、10、30、50、99 ******5%、10%、30%、50%、99%**********
  				percent2,
  				...
        ]
      }
    }
  }
}

percentile_ranks: percentile rank ******** percentiles **********,************** 1000、3000 ****************************,************ rank,******95,99,********** 95% ********** 1000 ****,99% ********** 3000 ****。

GET <index_name>/_search?size=0
{
  "aggs": {
    "<percentiles_name>": {
      "percentile_ranks": {
        "field": "<field_value>",
        "values": [
          rank1,
          rank2,
          ...
        ]
      }
    }
  }
}

10、********:Adjacency matrix

Elasticsearch****Adjacency Matrix************************,**************************************。Adjacency Matrix******************************。

9

10.1 **************

  • ************:************,Adjacency Matrix**********************************、********、**********,**************************。
  • ********:Adjacency Matrix********************************,************************、****************************。
  • ************:************,Adjacency Matrix******************************,********************、********、**********。
  • ********:Adjacency Matrix****************************************,******************************,**********************、********。

********,Adjacency Matrix********************************************************。****************************、******************,**********************************************。

10.2 ********

DELETE emails
PUT /emails/_bulk?refresh
{ "index" : { "_id" : 1 } }
{ "accounts" : ["a", "f"]}
{ "index" : { "_id" : 2 } }
{ "accounts" : ["a", "b"]}
{ "index" : { "_id" : 3 } }
{ "accounts" : ["c", "b"]}

GET emails/_search
GET emails/_search?size=0
{
  "aggs" : {
    "interactions" : {
      "adjacency_matrix" : {
        "filters" : {
          "A" : { "terms" : { "accounts" : ["a", "d"] }},
          "B" : { "terms" : { "accounts" : ["b", "e"] }},
          "C" : { "terms" : { "accounts" : ["c", "f"] }}
        }
      }
    }
  }
}

10

10.3 ****

**************,**********************。

PUT ****/_bulk?refresh
{ "index" : { "_id" : 1 } } 
{  "name":"******","accounts" : ["**********", "********"]}
{ "index" : { "_id" : 2 } } 
{ "name":"******","accounts" : ["**********", "********"]}
{ "index" : { "_id" : 3 } } 
{ "name":"******","accounts" : ["********", "********"]}

**************************************

GET ****/_search
{
  "size": 0,
  "aggs" : {
    "interactions" : {
      "adjacency_matrix" : {
        "filters" : {
          "****" : { "terms" : { "accounts.keyword" : ["**********", "****"] }},
          "****" : { "terms" : { "accounts.keyword" : ["********", "********"] }},
          "****" : { "terms" : { "accounts.keyword" : ["********", "********"] }}
        }
      },
      "aggs": {
        "top": {
          "top_hits": {
            "size": 10
          }
        }
      }
    }
  }
}

QQ + ****