elasticsearch—檢索與聚合(三)

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 特性實現得很完美,能夠提取的數據類型也沒有任何限制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章