1. 程式人生 > >ElasticSearch學習筆記之二十一 指標聚合

ElasticSearch學習筆記之二十一 指標聚合

ElasticSearch學習筆記之二十一 指標聚合

指標聚合

這種聚合從需要聚合的文件中提取出值進行指標計算。這些值通常從文件的欄位中提取出來,但是也可以使用 scripts。

數字型指標聚合是一個可以輸出數字型別值的指標聚合。 一些聚合輸出一個數組指標 (例如. avg) 我們稱之為單值數字型聚合 ,產生多個指標的(例如stats) 我們稱為多值數字型聚合。當這些聚合直接作為一些分組聚合的子聚合時,單值數字型聚合和多值數字型聚合就可以發揮巨大的作用,例如分組聚合可以對指標聚合後的返回結果進行排序。

Avg Aggregation

Avg Aggregation是一個從需要聚合的文件中提取欄位平均值

的單值數字型聚合. 這些值既可以從文件中提取也可以從script獲取。

假設有一組記錄學生成績的文件(0~100),我們可以這樣計算平均分:

POST /exams/_search?size=0
{
    "aggs" : {
        "avg_grade" : { #聚合的名稱
        	 "avg" : { #聚合的型別
        	 	"field" : "grade" 
        	 } 
        }
    }
}

上面的聚合會對所有的文件計算平均值。聚合的型別是avgfield 屬性指明瞭文件需要計算平均數的數字欄位。
返回的結果如下:

{
... "aggregations": { "avg_grade": {#聚合的名稱 "value": 75.0 } } }

聚合的名稱 (例如avg_grade ) 也會在返回的資訊作為關鍵字返回。

Script

通過script計算平均成績:

POST /exams/_search?size=0
{
    "aggs" : {
        "avg_grade" : {
            "avg" : {
                "script" : {
                    "source" : "doc.grade.value"
                }
            }
        }
    }
}

上面的語言會使用系統內建的指令碼語言進行解釋,並且不帶引數。使用一個檔案指令碼的完整語言如下:

POST /exams/_search?size=0
{
    "aggs" : {
        "avg_grade" : {
            "avg" : {
                "script" : {
                    "id": "my_script",
                    "params": {
                        "field": "grade"
                    }
                }
            }
        }
    }
}

Value Script

結果表明,考試的水平遠遠高於學生的水平,需要進行等級更正。我們可以使用值指令碼來獲得新的平均值。:

POST /exams/_search?size=0
{
    "aggs" : {
        "avg_corrected_grade" : {
            "avg" : {
                "field" : "grade",
                "script" : {
                    "lang": "painless",
                    "source": "_value * params.correction",
                    "params" : {
                        "correction" : 1.2
                    }
                }
            }
        }
    }
}

Missing value

missing 引數定義瞭如何處理缺少值的文件。預設情況下,它們將被忽略,但也有可能將它們視為具有值。

POST /exams/_search?size=0
{
    "aggs" : {
        "grade_avg" : {
            "avg" : {
                "field" : "grade",
                "missing": 10 
            }
        }
    }
}

grade欄位中沒有值的文件將與具有值10的文件落入相同的桶中。

Weighted Avg Aggregation

Weighted Avg Aggregation是一個從需要聚合的文件中提取欄位加權平均值的單值數字型聚合. 這些值既可以從文件中提取也可以從script獲取。

當計算一個規則平均值時,每個資料點都有一個相等的“權重”…它對最終值有同樣的貢獻。另一方面,加權平均值對每個資料點的權重不同。每個資料點對最終值的貢獻量是從文件中提取的,或者由指令碼提供。
加權平均值的計算公式

 ∑(value * weight) / ∑(weight)

正則平均值可以被認為是每個值都具有1的隱式權重的加權平均值。

weighted_avg Parameters

引數名稱 描述 是否需要預設值
value 欄位或者指令碼的加權配置值 Required
weight 欄位或者指令碼的加權配置 Required
format 返回數字的格式化 Optional
value_type 無對映的欄位或者純指令碼的預設值型別 Optional

每個欄位特定的值和權重物件配置

value Parameters

引數名稱 描述 是否需要預設值
field 提取值的欄位 Required
missing 預設預設值 Optional

weight Parameters

引數名稱 描述 是否需要預設值
field 權重值提取的欄位 Required
missing 權重預設預設值 Optional

例如
如果我們的文件有一個包含0-100個數字分數“grade”欄位和一個包含任意的數字權重“weight”欄位,,那麼我們可以使用:

POST /exams/_search
{
    "size": 0,
    "aggs" : {
        "weighted_grade": {
            "weighted_avg": {
                "value": {
                    "field": "grade"
                },
                "weight": {
                    "field": "weight"
                }
            }
        }
    }
}

返回結果如下

{
    ...
    "aggregations": {
        "weighted_grade": {
            "value": 70.0
        }
    }
}

雖然每個欄位允許多個值,但只允許一個權重。如果聚合遇到具有多於一個權重的文件(例如,權重欄位是多值欄位),它將丟擲異常。如果存在這種情況,則需要為權重欄位指定指令碼,並使用指令碼將多個值組合成要使用的單個值。

此單個權重將獨立地應用於從多值欄位中提取的每個值。

這個例子展示了一個具有多個值的單個文件將如何以單個權重平均化:

POST /exams/_doc?refresh
{
    "grade": [1, 2, 3],
    "weight": 2
}
POST /exams/_search
{
    "size": 0,
    "aggs" : {
        "weighted_grade": {
            "weighted_avg": {
                "value": {
                    "field": "grade"
                },
                "weight": {
                    "field": "weight"
                }
            }
        }
    }
}

這3個值(1, 2, and 3) 都會被包含進去和2的權重計算。
{

“aggregations”: {
“weighted_grade”: {
“value”: 2.0
}
}
}
聚合返回2作為結果,它與我們手工計算時的期望值相匹配: ((12) + (22) + (3*2)) / (2+2+2) == 2

Cardinality Aggregation

Cardinality Aggregation是一個從需要聚合的文件中計算不同值的近似計數(去重) 的單值數字型聚合. 這些值既可以從文件中提取也可以從script獲取。

假設您索引了商店銷售情況,並希望通過查詢計算銷售產品數量。

POST /sales/_search?size=0
{
    "aggs" : {
        "type_count" : {
            "cardinality" : {
                "field" : "type"
            }
        }
    }
}

返回結果如下

{
    ...
    "aggregations" : {
        "type_count" : {
            "value" : 3
        }
    }
}

Precision control

聚合也支援precision_threshold 精度控制引數:

POST /sales/_search?size=0
{
    "aggs" : {
        "type_count" : {
            "cardinality" : {
                "field" : "_doc",
                "precision_threshold": 100 
            }
        }
    }
}

precision_threshold 引數允許交易記憶體的準確性,並定義了一個獨特的計數以下計數預期接近準確。高於這個值,計數可能會變得更模糊。最大支援值是40000,高於這個數的閾值將具有與閾值40000相同的效果。預設值為3000。

Counts are approximate

計算精確計數需要將值載入到雜湊集並返回其大小。當處理高基數集和/或大值作為所需的記憶體使用以及節點之間通訊那些每碎片集的需要時,這無法擴充套件,這會利用叢集的許多資源。

這種基數聚合是基於HyperLog++演算法的,它基於具有以下一些有趣的屬性的值的雜湊進行計數:

  • 可配置的精度,決定如何交易記憶體的準確性,
  • 低基數集精度高,
  • 固定記憶體使用率:無論存在數百或數十億個惟一值,記憶體使用率僅取決於配置的精度。
    -對於C的精確閾值,我們使用的實現需要大約c* 8位元組。

下面的圖表顯示了閾值前後的誤差是如何變化的:

cardinality_error
對於所有3個閾值,計數一直精確到配置的閾值(儘管不能保證,但很可能是這樣)。請注意,即使閾值低至100,錯誤仍然很低,即使在數以百萬計的專案。