1.聚合
聚合 aggregations 有助於基於搜索查詢提供聚合數據。它基於稱爲聚合的簡單構建塊,可以進行組合以構建複雜的數據摘要。
聚合 aggregations 可以看作是在一組文檔上建立分析信息的工作單元。執行的上下文定義此文檔集是什麼(例如,頂級聚合在搜索請求的已執行查詢/過濾器的上下文中執行)。
有許多不同類型的聚合,每種聚合都有自己的目的和輸出。爲了更好地理解這些類型,通常更容易將它們分爲四個主要元素:
- Bucketing
生成存儲桶的一組聚合,其中每個存儲桶都與一個鍵和一個文檔條件相關聯。執行聚合時,將對上下文中的每個文檔評估所有存儲桶條件,並且當條件匹配時,該文檔將被視爲“落入”相關存儲桶。到聚合過程結束時,我們將得到一個存儲桶列表-每個存儲桶都有一組“屬於”的文檔。 - Metric
聚合可跟蹤和計算一組文檔的指標。 - Matrix
一類聚合,可在多個字段上進行操作,並根據從請求的文檔字段中提取的值生成矩陣結果。與指標和存儲桶聚合不同,此聚合系列尚不支持腳本。 - Pipeline
彙總其他彙總及其相關指標的輸出的彙總
基於前篇文章的一個業務需求:支持管理者對員工目錄做分析。允許我們基於數據生成一些精細的分析結果。聚合與 SQL 中的 GROUP BY 類似但更強大。
es中的所有模擬數據:
...
{
"_index": "megacorp",
"_type": "employee",
"_id": "3",
"_score": 1,
"_source": {
"first_name": "Douglas",
"last_name": "Fir",
"age": 35,
"about": "I like to build cabinets",
"interests": [ "forestry" ]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "2",
"_score": 1,
"_source": {
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [ "music" ]
}
}
舉個例子,挖掘出員工中最受歡迎的興趣愛好:
GET /megacorp/employee/_search
{
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
}
返回結果如下:
{
...
"hits": { ... },
"aggregations": {
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "forestry",
"doc_count": 1
},
{
"key": "sports",
"doc_count": 1
}
]
}
}
}
可以看到,兩位員工對音樂感興趣,一位對林業感興趣,一位對運動感興趣。這些聚合的結果數據並非預先統計,而是根據匹配當前查詢的文檔即時生成的。如果想知道叫 Smith 的員工中最受歡迎的興趣愛好,可以直接構造一個組合查詢:
GET /megacorp/employee/_search
{
"query": {
"match": {
"last_name": "smith"
}
},
"aggs": {
"all_interests": {
"terms": {
"field": "interests"
}
}
}
}
all_interests 聚合已經變爲只包含匹配查詢的文檔:
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2
},
{
"key": "sports",
"doc_count": 1
}
]
}
聚合還支持分級彙總 。比如,查詢特定興趣愛好員工的平均年齡:
GET /megacorp/employee/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}
得到的聚合結果有點兒複雜,但理解起來還是很簡單的:
...
"all_interests": {
"buckets": [
{
"key": "music",
"doc_count": 2,
"avg_age": {
"value": 28.5
}
},
{
"key": "forestry",
"doc_count": 1,
"avg_age": {
"value": 35
}
},
{
"key": "sports",
"doc_count": 1,
"avg_age": {
"value": 25
}
}
]
}
輸出基本是第一次聚合的加強版。依然有一個興趣及數量的列表,只不過每個興趣都有了一個附加的 avg_age 屬性,代表有這個興趣愛好的所有員工的平均年齡。
即使現在不太理解這些語法也沒有關係,依然很容易瞭解到複雜聚合及分組通過 Elasticsearch 特性實現得很完美,能夠提取的數據類型也沒有任何限制。