Elasticsearch——聚合搜索

聚合分析簡介

聚合分析:英文為Aggregation,是es除搜索功能外提供的針對es數據做統計分析的功能。

  • 功能豐富,提供Bucket、Metric、Pipeline等多種分析方式,可以滿足大部分的分析需求。
  • 實時性高,所有的計算結果都是即時返回的,而hadoop等大數據系統一般都是 T+1級別的。

聚合框架有助于根據搜索查詢提供聚合數據。聚合查詢是數據庫中重要的功能特性,ES作為搜索引擎兼數據庫,同樣提供了強大的聚合分析能力。它基于查詢條件來對數據進行分桶、計算的方法。有點類似于 SQL 中的 group by 再加一些函數方法的操作。聚合可以嵌套,由此可以組成復雜的操作(Bucketing聚合可以包含sub-aggregation)。

聚合分析作為search的一部分,聚合計算的值可以取字段的值,也可是腳本計算的結果。查詢請求體中以aggregations節點的語法定義:


image.png

聚合分析-分類

Elasticsearch除全文檢索功能外提供的針對Elasticsearch數據做統計分析的功能。它的實時性高,所有的計算結果都是即時返回。

Elasticsearch將聚合分析主要分為如下4類:

  • Bucket-分桶類型:分桶類型,類似SQL中的GROUP BY語法 (滿足特定條件的文檔的集合)。
  • Metric-指標分析類型:指標分析類型,如計算最大值、最小值、平均值等等 (對桶內的文檔進行聚合分析的操作)。
  • Pipeline-管道分析類型:管道分析類型,基于上一級的聚合分析結果進行在分析。
  • Matrix-矩陣分析類型:矩陣分析類型(聚合是一種面向數值型的聚合,用于計算一組文檔字段中的統計信息)。

指標(metric)和 桶(bucket)

雖然Elasticsearch有四種聚合方式,但在一般實際開發中,用到的比較多的就是Metric和Bucket。

桶(bucket)
  • a、簡單來說桶就是滿足特定條件的文檔的集合。
  • b、當聚合開始被執行,每個文檔里面的值通過計算來決定符合哪個桶的條件,如果匹配到,文檔將放入相應的桶并接著開始聚合操作。
  • c、桶也可以被嵌套在其他桶里面。
指標(metric)
  • a、桶能讓我們劃分文檔到有意義的集合,但是最終我們需要的是對這些桶內的文檔進行一些指標的計算。分桶是一種達到目的地的手段:它提供了一種給文檔分組的方法來讓我們可以計算感興趣的指標。
  • b、大多數指標是簡單的數學運算(如:最小值、平均值、最大值、匯總),這些是通過文檔的值來計算的。

metric聚合分析

主要分如下兩類:

  • 單值分析,只輸出一個分析結果
    • min、max、avg、sum
    • cardinality

其中,Min、Max、Avg、Sum 這些很容易理解,在這里說一下 Cardinality,它是指不同數值的個數,相當于 SQL 中的 distinct。

  • 多值分析,輸出多個分析結果
    • stats、extended stats
    • percentile、percentile rank
    • top hits
  • Stats 是做多樣的數據分析,可以一次性得到最大值、最小值、平均值、中值等數據。
  • Extended Stats 是對 Stats 的擴展,包含了更多的統計數據,比如方差、標準差等。
  • Percentiles 和 Percentile Ranks 是百分位數的一個統計。
  • Top Hits 一般用于分桶后獲取桶內最匹配的頂部文檔列表,即詳情數據。

Metric聚合分析-Min

返回數值類字段的最小值

GET /book/_search
{
  "size":0,
  "aggs":{
    "min_price":{
      "min":{
        "field":"price"
      }
    }
  }
}

Metric聚合分析-Max

返回數值類字段的最大值

GET /book/_search
{
  "size":0,
  "aggs":{
    "max_price":{
      "max":{
        "field":"price"
      }
    }
  }
}

Metric聚合分析-Sum

返回數值類字段的和

GET /book/_search
{
  "size":0,
  "aggs":{
    "sum_price":{
      "sum":{
        "field":"price"
      }
    }
  }
}

一次性返回多個結果集

GET /book/_search
{
  "size":0,
  "aggs":{
    "min_price":{
      "min":{
        "field":"price"
      }
    },
    "max_price":{
      "max":{
        "field":"price"
      }
    }
  }
}

Metric聚合分析-Avg

返回數值類字段的平均值

GET /book/_search
{
  "size":0,
  "aggs":{
    "avg_price":{
      "avg":{
        "field":"price"
      }
    }
  }
}

值統計

Value Count Aggregation,值計數聚合。計算聚合文檔中某個值(可以是特定的數值型字段,也可以通過腳本計算而來)的個數。該聚合一般域其它 single-value 聚合聯合使用,比如在計算一個字段的平均值的時候,可能還會關注這個平均值是由多少個值計算而來。

GET /book/_search
{
  "size":0,
  "aggs":{
    "count_of_tags":{
      "value_count":{
        "field":"tags"
      }
    }
  }
}

Metric聚合分析-Cardinality

Cardinality:意為集合的勢,或者基數,是指不同數值的個數,類似SQL中的distinct count概念。

GET /book/_search
{
  "size":0,
  "aggs":{
    "count_of_tags":{
      "cardinality":{
        "field":"tags"
      }
    }
  }
}

Metric聚合分析-Stats

返回一系列數值類型的統計值,包含min、max、avg、sum和count。

GET /book/_search
{
  "size":0,
  "aggs":{
    "stats_price":{
      "stats":{
        "field":"price"
      }
    }
  }
}

Metric聚合分析-Extended Stats

Extended Stats Aggregation,擴展統計聚合。它屬于multi-value,比stats多4個統計結果: 平方和、方差、標準差、平均值加/減兩個標準差的區間。

GET /book/_search
{
  "size":0,
  "aggs":{
    "stats_price":{
      "extended_stats":{
        "field":"price"
      }
    }
  }
}

Metric聚合分析-Percentile

百分位數統計:
Percentiles Aggregation,百分比聚合。它屬于multi-value,對指定字段(腳本)的值按從小到大累計每個值對應的文檔數的占比(占所有命中文檔數的百分比),返回指定占比比例對應的值。默認返回[ 1, 5, 25, 50, 75, 95, 99 ]分位上的值。

GET /book/_search
{
  "size":0,
  "aggs":{
    "percents_price":{
      "percentiles":{
        "field":"price"
      }
    }
  }
}

Metric聚合分析-Percentile Rank

百分位數統計:
Percentile Ranks Aggregation,統計價格小于40和價格小于60的文檔的占比,這里需求可以使用。

GET /book/_search
{
  "size":0,
  "aggs":{
    "gge_perc_rank":{
      "percentile_ranks":{
        "field":"price",
         "values": [
          40,
          60
        ]
      }
    }
  }
}

Metric聚合分析-Top Hits

Top Hits Aggregation,最高匹配權值聚合。獲取到每組前n條數據,相當于sql 中Top(group by 后取出前n條)。它跟蹤聚合中相關性最高的文檔,該聚合一般用做 sub-aggregation,以此來聚合每個桶中的最高匹配的文檔,較為常用的統計。

GET /book/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "name",
        "size": 2
      },
      "aggs": {
        "top_tag_hits": {
          "top_hits": {
            "size": 2
          }
        }
      }
    }
  }
}

一般用于分桶后獲取該桶內最匹配的頂部文檔列表,即詳情數據

GET /book/_search
{
  "size":0,
  "aggs": {
    "top_tags": {
      "terms": {
        "field": "name",  #根據name進行分組 每組顯示前3個文檔
        "size": 3
      },
      "aggs": {
        "top_sales_hits": {
          "top_hits": {
            "sort": [
              {
                "timestamp": {
                  "order": "desc"  #按照時間進行倒敘排序
                }
              }
            ],
            "_source": {
              "includes": [ "name", "price" ]  #只顯示文檔指定字段
            },
            "size" : 1
          }
        }
      }
    }
  }
}

Geo Bounds Aggregation

Geo Bounds Aggregation,地理邊界聚合。基于文檔的某個字段(geo-point類型字段),計算出該字段所有地理坐標點的邊界(左上角/右下角坐標點)。

GET index/type/_search?search_type=count
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "viewport": {
      "geo_bounds": {
        "field": "location",
        "wrap_longitude": true //是否允許地理邊界與國際日界線存在重疊
      }
    }
  }
}
{//返回,
    ...
    "aggregations": {
        "viewport": {
            "bounds": {
                "top_left": { //這個矩形區域左上角坐標
                    "lat": 80.45,
                    "lon": -160.22
                },
                "bottom_right": {//這個矩形區域右下角坐標
                    "lat": 40.65,
                    "lon": 42.57
                }
            }
        }
    }
}

Geo Centroid Aggregation

Geo Centroid Aggregation,地理重心聚合。基于文檔的某個字段(geo-point類型字段),計算所有坐標的加權重心。

GET index/type/_search?search_type=count
{
    "query" : {
        "match" : { "crime" : "burglary" }
    },
    "aggs" : {
        "centroid" : {
            "geo_centroid" : {
                "field" : "location" 
            }
        }
    }
}
{//輸出
    ...
    "aggregations": {
        "centroid": {
            "location": {      //重心經緯度
                "lat": 80.45,
                "lon": -160.22
            }
        }
    }
}

Bucket桶聚合分析

Bucket Aggregations,桶聚合。

它執行的是對文檔分組的操作(與sql中的group by類似),把滿足相關特性的文檔分到一個桶里,即桶分,輸出結果往往是一個個包含多個文檔的桶(一個桶就是一個group)。

它有一個關鍵字(field、script),以及一些桶分(分組)的判斷條件。執行聚合操作時候,文檔會判斷每一個分組條件,如果滿足某個,該文檔就會被分為該組(fall in)。

它不進行權值的計算,他們對文檔根據聚合請求中提供的判斷條件(比如:{"from":0, "to":100})來進行分組(桶分)。桶聚合還會額外返回每一個桶內文檔的個數。

它可以包含子聚合——sub-aggregations(權值聚合不能包含子聚合,可以作為子聚合),子聚合操作將會應用到由父聚合產生的每一個桶上。

它根據聚合條件,可以只定義輸出一個桶;也可以輸出多個(multi-bucket);還可以在根據聚合條件動態確定桶個數(比如:terms aggregation)。

按照Bucket的分桶策略,常見的Bucket聚合分析如下:

  • Terms
  • Range
  • Date Range
  • Histogram
  • Date Histogram

Bucket聚合分析-Terms

Terms Aggregation,詞聚合。基于某個field,該 field 內的每一個【唯一詞元】為一個桶,并計算每個桶內文檔個數。默認返回順序是按照文檔個數多少排序。它屬于multi-bucket。當不返回所有 buckets 的情況(它size控制),文檔個數可能不準確。

該分桶策略最簡單,直接按照term來分桶,如果是text類型,則按照分詞后的結果分桶。

GET /book/_search
{
  "aggs" : {
    "age_terms" : {
      "terms" : { 
        "field" : "name",
        "size" : 10,      #size用來定義需要返回多個 buckets(防止太多),默認會全部返回。
        "order" : { "_count" : "asc" },  #根據文檔計數排序,根據分組值排序({ "_key" : "asc" })
        "min_doc_count": 10,            #只返回文檔個數不小于該值的 buckets
        "include" : ".*sport.*",        #包含過濾
        "exclude" : "water_.*",         #排除過濾
        "missing": "N/A" 
      }
    }
  }
}
GET /book/_search
{
  "aggs": {
    "age_terms": {
      "terms": {
        "field": "price",
        "size": 5,
        "shard_size": 20, 
        "show_term_doc_count_error": true 
      }
    }
  }
}

Bucket聚合分析- Range

Range Aggregation,范圍分組聚合。基于某個值(可以是 field 或 script),以【字段范圍】來桶分聚合。范圍聚合包括 from 值,不包括 to 值(區間前閉后開)。它屬于multi-bucket。

GET /book/_search
{
  "size":0,
  "aggs": {
    "price_range": {
      "range": {
        "field": "price",
        "ranges": [ 
          {
            "to":20
          },
          {
            "from": 20,
            "to": 40
          },
          {
            "from": 60
          }
        ]
      },
      "aggs": {
        "bmax": {
          "max": {
            "field": "price"
          }
        }
      }
    }
  }
}

Bucket聚合分析- Date Range

Date Range Aggregation,日期范圍聚合。基于日期類型的值,以【日期范圍】來桶分聚合。期范圍可以用各種 Date Math 表達式。同樣的,包括 from 的值,不包括 to 的值。它屬于multi-bucket。

GET /book/_search
{
  "aggs": {
    "range": {
      "date_range": {
        "field": "timestamp",
        "format": "MM-yyy",
        "ranges": [   
          {
            "to": "now-10M/M"
          },
          {
            "from": "now-10M/M"
          }
        ]
      }
    }
  }
}

Bucket聚合分析- Histogram 時間柱狀聚合

直方圖,以固定間隔的策略來分割數據。

你要先了解下Histogram Aggregation,直方圖聚合。基于文檔中的某個【數值類型】字段,通過計算來動態的分桶。它屬于multi-bucket。

{
  "aggs" : {
    "prices" : {
      "histogram" : {
        "field" : "price",      //字段,必須為數值類型
        "calendar_interval" : 50,       //分桶間距
        "min_doc_count" : 1,    //最少文檔數桶過濾,只有不少于這么多文檔的桶才會返回
        "extended_bounds" : { //范圍擴展
          "min" : 0,
          "max" : 500
        },
        "order" : { "_count" : "desc" },//對桶排序,如果 histogram 聚合有一個權值聚合類型的"直接"子聚合,那么排序可以使用子聚合中的結果
        "keyed":true, //hash結構返回,默認以數組形式返回每一個桶
        "missing":0 //配置缺省默認值
      }
    }
  }
}
GET /book/_search
{
  "aggs" : {
    "salary_hist" : {
      "histogram" : {
        "field" : "price",
        "interval" : 50,
        "min_doc_count" : 1,  
        "extended_bounds" : { 
          "min" : 0,
          "max" : 50
        },
        "order" : { "_count" : "desc" },
        "keyed":true, 
        "missing":0 
      }
    }
  }
}

Bucket聚合分析- Date Histogram

針對日期的直方圖或者柱狀圖,是時序數據分析中常用的聚合分析類型。

Date Histogram Aggregation,日期直方圖聚。基于日期類型,以【日期間隔】來桶分聚合。可用的時間間隔類型為:year、quarter、month、week、day、hour、minute、second,其中,除了year、quarter 和 month,其余可用小數形式。

GET /book/_search
{
  "aggs" : {
    "articles_over_time" : {
      "date_histogram" : {
        "field" : "timestamp",
        "calendar_interval" : "month",
        "format" : "yyyy-MM-dd",
        "time_zone": "+08:00"
      }
    }
  }
}

Missing Aggregation

Missing Aggregation,缺失值的桶聚合

GET /book/_search
{
  "aggs" : {
    "account_without_a_age" : {
      "missing" : { "field" : "name" }
    }
  }
}

IP范圍聚合

IP Range Aggregation,基于一個 IPv4 字段,對文檔進行【IPv4范圍】的桶分聚合。和 Range Aggregation 類似,只是應用字段必須是 IPv4 數據類型。它屬于multi-bucket。

GET /ip_addresses/_search
{
    "size": 10,
    "aggs" : {
        "ip_ranges" : {
            "ip_range" : {
                "field" : "ip",
                "ranges" : [
                    { "to" : "10.0.0.5" },
                    { "from" : "10.0.0.5" }
                ]
            }
        }
    }
}

bucket和metric聚合分析

Bucket聚合分析允許通過添加子分析來進一步進行分析,該子分析可以是Bucket也可以是Metric,這也使得es的聚合分析能力變得異常強大

分桶之后再分桶:

GET /book/_search
{
  "size":0,
  "aggs" : {
    "tags" : {
      "terms": { 
        "field" : "tags",
        "size": 5
      },
      "aggs" : {
        "price_range" : {
          "range": { 
            "field" : "price",
            "ranges": [
              {"to":20},
              {"from": 20,"to": 50},
              {"from": 80}
            ]
          }
        }
      }
    }
  }
}
image.png

分桶后進行數據分析:

GET /book/_search
{
  "size":0,
  "aggs" : {
    "tags" : {
      "terms": { 
        "field" : "tags",
        "size": 5
      },
      "aggs" : {
        "price" : {
          "stats": { 
            "field" : "price"
          }
        }
      }
    }
  }
}

Nested Aggregation

Nested Aggregation,嵌套類型聚合。基于嵌套(nested)數據類型,把該【嵌套類型的信息】聚合到單個桶里,然后就可以對嵌套類型做進一步的聚合操作。

矩陣聚合

Matrix,矩陣聚合。此功能是實驗性的,在將來的版本中可能會完全更改或刪除。

它對多個字段進行操作并根據從請求的文檔字段中提取的值生成矩陣結果的聚合系列。與度量聚合和桶聚合不同,此聚合系列尚不支持腳本編寫。

pipeline聚合分析

Pipeline,管道聚合。它對其它聚合操作的輸出(桶或者桶的某些權值)及其關聯指標進行聚合,而不是文檔,是一種后期對每個分桶的一些計算操作。管道聚合的作用是為輸出增加一些有用信息。

管道聚合不能包含子聚合,但是某些類型的管道聚合可以鏈式使用(比如計算導數的導數)。

管道聚合大致分為兩類:

  • parent:它輸入是其【父聚合】的輸出,并對其進行進一步處理。一般不生成新的桶,而是對父聚合桶信息的增強。

  • sibling:它輸入是其【兄弟聚合】的輸出。并能在同級上計算新的聚合。

管道聚合通過 buckets_path 參數指定他們要進行聚合計算的權值對象,bucket_path語法

聚合分隔符:">",指定父子聚合關系,如:"my_bucket>my_stats.avg"
權值分隔符: ".",指定聚合的特定權值
聚合名稱:<name of the aggregation>,直接指定聚合的名稱
權值:<name of the metric>,直接指定權值
完整路徑:agg_name[> agg_name]*[. metrics],綜合利用上面的方式指定完整路徑
特殊值:"_count",輸入的文檔個數

特殊情況:

  • 要進行 pipeline aggregation 聚合的對象名稱或權值名稱包含小數點,"buckets_path": "my_percentile[99.9]"
  • 處理對象中包含空桶(無文檔的桶分),參數 gap_policy,可選值有 skip、insert_zeros

Pipeline的分析結果會輸出到原結果中,根據輸出位置的不同,分為以下兩類
Parent結果內嵌到現有的聚合分析結果中
* Derivative:求導導數
* Moving Average:平均
* Cumulative Sum-Sibling:累計求和

結果與現有聚合分析結果同級
* Max/Min/Avg/Sum Bucket
* Stats/Extended Stats Bucket
* Percentiles Bucket

Avg Max Min Sum:sibliing

  • Avg Bucket Aggregation,桶均值聚合。基于兄弟聚合的某個權值,求所有桶的權值均值。使用規則:用于計算的兄弟聚合必須是多桶聚合。用于計算的權值必須是數值類型。

  • Max Bucket Aggregation,桶最大值聚合。基于兄弟聚合的某個權值,輸出權值最大的那一個桶。

  • Min Bucket Aggregation,桶最小值聚合。基于兄弟聚合的某個權值,輸出權值最小的一個桶。

  • Sum Bucket Aggregation,桶求和聚合。基于兄弟聚合的權值,對所有桶的權值求和。

Pipeline聚合分析Sibling-Min Bucket

找出所有Bucket中值最小的Bucket名稱和值:

GET /book/_search
{
  "size": 0, 
  "aggs" : {
    "tags" : {
      "terms": {
        "field" : "tags"
        
      },
      "aggs": {
        "price_avg": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "min_price": {
      "min_bucket": {
        "buckets_path": "tags>price_avg" 
      }
    }
  }
}

Pipeline聚合分析Sibling-Max Bucket

找出所有Bucket中值最大的Bucket名稱和值:

GET /book/_search
{
  "size": 0, 
  "aggs" : {
    "tags" : {
      "terms": {
        "field" : "tags"
        
      },
      "aggs": {
        "price_avg": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "max_price": {
      "max_bucket": {
        "buckets_path": "tags>price_avg" 
      }
    }
  }
}

Pipeline聚合分析Sibling-Avg Bucket

計算所有Bucket的平均值:

GET /book/_search
{
  "size": 0, 
  "aggs" : {
    "tags" : {
      "terms": {
        "field" : "tags"
        
      },
      "aggs": {
        "price_avg": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "avg_price": {
      "avg_bucket": {
        "buckets_path": "tags>price_avg" 
      }
    }
  }
}

Pipeline聚合分析Sibling-Sum Bucket

計算所有Bucket的值的總和:

GET /book/_search
{
  "size": 0, 
  "aggs" : {
    "tags" : {
      "terms": {
        "field" : "tags"
        
      },
      "aggs": {
        "price_avg": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "avg_price": {
      "sum_bucket": {
        "buckets_path": "tags>price_avg" 
      }
    }
  }
}

Pipeline聚合分析Sibling-Stats Bucket

Stats Bucket Aggregation,桶統計信息聚合。基于兄弟聚合的某個權值,對【桶的信息】進行一些統計學運算(總計多少個桶、所有桶中該權值的最大值、最小等)。用于計算的權值必須是數值類型。用于計算的兄弟聚合必須是多桶聚合類型。

計算所有Bucket的值的Stats分析值:

GET /book/_search
{
  "size": 0, 
  "aggs" : {
    "tags" : {
      "terms": {
        "field" : "tags"
        
      },
      "aggs": {
        "price_avg": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "stats_price": {
      "stats_bucket": {
        "buckets_path": "tags>price_avg" 
      }
    }
  }
}

Pipeline聚合分析Sibling-Percentiles Bucket

計算所有Bucket的值的百分位數:

GET /book/_search
{
  "size": 0, 
  "aggs" : {
    "tags" : {
      "terms": {
        "field" : "tags"
      },
      "aggs": {
        "price_avg": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "percentiles_price": {
      "percentiles_bucket": {
        "buckets_path": "tags>price_avg" 
      }
    }
  }
}

Derivative Aggregation:parent

Derivative Aggregation,求導聚合。基于父聚合(只能是histogram或date_histogram類型)的某個權值,對權值求導。用于求導的權值必須是數值類型。封閉直方圖(histogram)聚合的 min_doc_count 必須是 0。

計算Bucket值得導數:

GET /book/_search
{
  "aggs" : {
    "sales_per_month" : {
      "date_histogram" : {
        "field" : "timestamp",
        "calendar_interval" : "month"
      },
      "aggs": {
        "sum_price": {
          "sum": {
            "field": "price"
          }
        },
        "sales_deriv": {
          "derivative": {
            "buckets_path": "sum_price"  
          }
        }
      }
    }
  }
}

Moving Average Aggregation:parent

Moving Average Aggregation,窗口平均值聚合。基于已經排序過的數據,計算出處在當前出口中數據的平均值。比如窗口大小為 5 ,對數據 1—10 的部分窗口平均值如下:

  • (1 + 2 + 3 + 4 + 5) / 5 = 3
  • (2 + 3 + 4 + 5 + 6) / 5 = 4
  • (3 + 4 + 5 + 6 + 7) / 5 = 5
  • etc
GET /book/_search
{
  "size": 0,
  "aggs": {
    "my_date_histo":{
      "date_histogram":{
        "field":"timestamp",
        "calendar_interval":"1M"
      },
      "aggs":{
        "the_sum":{
          "sum":{ "field": "price" }
        },
        "the_movavg":{
          "moving_avg":{
            "buckets_path": "the_sum",
            "window" : 30,      
            "model" : "simple"
          }
        }
      }
    }
  }
}

Pipeline聚合分析Parent-Cumulative Sum

計算Bucket的值的累加和:

GET /book/_search
{
  "size": 0, 
  "aggs" : {
    "my_date_histo":{
      "date_histogram":{
        "field":"timestamp",
        "calendar_interval":"year",
        "min_doc_count": 0
      },
      "aggs": {
        "price_avg": {
          "avg": {
            "field": "price"
          }
        },
        "cumulative_sum_price": {
          "cumulative_sum": {
            "buckets_path": "price_avg" 
          }
        }
      }
    }
  }
}

作用范圍

es聚合分析默認作用范圍是query的結果集,可以通過如下的方式改變其作用范圍:

  • filter
  • post_filter
  • global

filter Aggregation 作用范圍

Filter Aggregation,過濾聚合。基于一個條件,來對當前的文檔進行過濾的聚合。

為某個聚合分析設定過濾條件,從而在不更改整體query語句的情況下修改了作用范圍

GET /book/_search
{
  "size": 0, 
  "aggs": {
    "price": {
      "filter": {
        "range":{
          "price": {
            "to":50
          }
        }
      },
      "aggs": {
        "tags": {
          "terms": {
            "field": "tags"
          }
        }
      }
    }
  }
}

Filters Aggregation 作用范圍

Filters Aggregation,多過濾聚合。基于多個過濾條件,來對當前文檔進行【過濾】的聚合,每個過濾都包含所有滿足它的文檔(多個bucket中可能重復),先過濾再聚合。它屬于multi-bucket。

GET /book/_search
{
  "size": 0,
  "aggs": {
    "messages": {
      "filters": { // 配置過濾條件,支持 HASH 或 數組格式
        "filters": {
          "errors": {
            "match": {
              "body": "error"
            }
          },
          "warnings": {
            "match": {
              "body": "warning"
            }
          }
        }
      }
    }
  }
}

作用范圍-post_filter

作用于文檔過濾,但在聚合分析后生效

GET /book/_search
{
  "size": 0, 
 "aggs": {
    "tags": {
      "terms": {
        "field": "tags"
      }
    }
  },
  "post_filter": {
    "match":{
      "tags":"java spring"
    }
  }
}

作用范圍 Global aggregators

Global aggregators全局匯總:在搜索執行上下文中定義所有文檔的單個存儲桶。此上下文由您要搜索的索引和文檔類型定義,但不受搜索查詢本身的影響。

作用于文檔過濾,但在聚合分析后生效

GET /book/_search
{
  "size": 0, 
  "query": {
    "match": {
      "name": "java 程序員"
    }
  },
  "aggs": {
    "avg_price": {
      "avg": {
        "field": "price"
      }
    },
    "all":{
      "global":{},
      "aggs": {
        "all_brand_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}
GET /book/_search
{
  "query": {
    "match": { "name": "java 程序員" }
  },
  "aggs": {
    "all_products": {
      "global": {}, 
      "aggs": {     
      "avg_price": { "avg": { "field": "price" } }
      }
    },
    "java 程序員": { "avg": { "field": "price" } }
  }
}

Bucket Script Aggregation:parent

Bucket Script Aggregation,桶腳本聚合。基于父聚合的【一個或多個權值】,對這些權值通過腳本進行運算。用于計算的父聚合必須是多桶聚合。用于計算的權值必須是數值類型。執行腳本必須要返回數值型結果。

Bucket Selector Aggregation:parent

Bucket Selector Aggregation,桶選擇器聚合。基于父聚合的【一個或多個權值】,通過腳本對權值進行計算,并決定父聚合的哪些桶需要保留,其余的將被丟棄。用于計算的父聚合必須是多桶聚合。用于計算的權值必須是數值類型。運算的腳本必須是返回 boolean 類型,如果腳本是腳本表達式形式給出,那么允許返回數值類型。

Serial Differencing Aggregation:parent

Serial Differencing Aggregation,串行差分聚合。基于父聚合(只能是histogram或date_histogram類型)的某個權值,對權值值進行差分運算,(取時間間隔,后一刻的值減去前一刻的值:f(X) = f(Xt) – f(Xt-n))。用于計算的父聚合必須是多桶聚合。

Extended Stats Bucket Aggregation:sibliing

Extended Stats Bucket Aggregation,擴展桶統計聚合。基于兄弟聚合的某個權值,對【桶信息】進行一系列統計學計算(比普通的統計聚合多了一些統計值)。用于計算的權值必須是數值類型。用于計算的兄弟聚合必須是多桶聚合類型。

Percentiles Bucket Aggregation:sibliing

Percentiles Bucket Aggregation,桶百分比聚合。基于兄弟聚合的某個權值,計算權值的百分比。用于計算的權值必須是數值類型。用于計算的兄弟聚合必須是多桶聚合類型。對百分比的計算是精確的(不像Percentiles Metric聚合是近似值),所以可能會消耗大量內存。

小結:ES默認給 大多數字段啟用doc values,所以在一些搜索場景大大的節省了內存使用量,但是需要注意的是只有不分詞的 string 類型的字段才能使用這種特性。使聚合運行在 not_analyzed 字符串而不是 analyzed 字符串,這樣可以有效的利用 doc values 。

聚合分析排序

可以使用自帶的關鍵數據進行排序,比如:

  • _count文檔數
  • _key按照key值排序

原理與精準度問題

Min聚合得執行流程

Terms聚合的執行流程

Terms并不永遠準確

數據分散在多Shard上,Coordinating Node無法得悉數據全貌;所以不準確。

Terms不準確的解決辦法

  • 設置Shard數為1,消除數據分散的問題,但無法承載大數據量。
  • 合理設置Shard Size大小,即每次從Shard上額外多獲取數據,以提升準確度。

Shard_Size大小的設定方法

terms聚合返回結果中有如下兩個統計值:

  • doc_count_error_upper_bound被遺漏的term可能的最大值
  • sum_other_other_doc_count返回結果bucket的term外其他term的文檔總數

設定show_term_doc_count_error可以查看每個bucket誤算的最大值

  • Shard Size默認大小如下:

    • shard size = (size x 1.5) +10
  • 通過調整Shard Size的大小降低doc_count_error_upper_bound來提升準確度

    • 增大了整體的計算量,從而降低了響應時間

近似統計算法

在ES的聚合分析中, Cardinality和Percentile分析使用的是近似統計算法

  • 結果是近似準確的,但不一定精準
  • 可以通過參數的調整使其結果精準,但同時也意味著更多的計算時間和更大的性能消耗

參考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html

https://blog.csdn.net/alex_xfboy/article/details/86100037

https://blog.csdn.net/bingdianone/article/details/86611509

https://zhuanlan.zhihu.com/p/115362603

https://www.cnblogs.com/qdhxhz/p/11556764.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容