掌握 ElasticSearch 聚合查詢:Aggregations 入門與實戰

掌握 ElasticSearch 聚合查詢:Aggregations 入門與實戰

    • 一、引言 (Introduction)
    • 二、數據準備 (Data Preparation)
      • 2.1 創建索引 (Create Index)
      • 2.2 批量導入數據 (Bulk Import Data)
    • 三、聚合查詢基礎 (Aggregation Basics)
      • 3.1 什么是聚合查詢?(What are Aggregations?)
      • 3.2 聚合查詢的基本結構 (Basic Aggregation Structure)
      • 3.3 聚合類型 (Aggregation Types)
    • 四、指標聚合 (Metrics Aggregations)
      • 4.1 `avg` (平均值)
      • 4.2 `min` (最小值)
      • 4.3 `max` (最大值)
      • 4.4 `sum` (總和)
      • 4.5 `stats` (統計信息)
      • 4.6 `value_count` (值計數)
      • 4.7 `cardinality` (基數/去重計數)
    • 五、桶聚合 (Bucket Aggregations)
      • 5.1 `terms` (詞條聚合)
      • 5.2 嵌套桶聚合
    • 六、管道聚合 (Pipeline Aggregations)
      • 6.1 什么是管道聚合?
      • 6.2 `min_bucket` (最小桶)
      • 6.3 其他管道聚合
    • 七、實戰案例 (Practical Examples)
      • 案例 1:統計每個產品類別中,價格最高的產品的價格,并按最高價格降序排列
      • 案例 2:找出每個月銷售額最高的日期
    • 八、總結 (Conclusion)

一、引言 (Introduction)

在信息檢索和數據分析的世界中,我們常常需要做的不僅僅是找到匹配特定關鍵詞的文檔。很多時候,我們需要從海量數據中提取出更深層次的、有價值的洞察。例如:

  • 我想知道我的電商網站上所有商品的平均價格是多少?
  • 哪個產品類別下的商品數量最多?
  • 我的網站上有多少種不同的商品品牌?
  • 在過去的一年中,每個月的銷售總額是多少?
  • 哪一天的銷售額是最高的?

這些問題都涉及對數據的統計和分析,而不僅僅是簡單的搜索。為了滿足這些需求,Elasticsearch 提供了強大的聚合查詢(Aggregations) 功能。聚合查詢就像一個多功能的瑞士軍刀,或者說是一個強大的數據分析工具箱,它允許你對數據進行各種分組、統計和計算,從而提取出隱藏在數據背后的關鍵信息。

你可以把聚合查詢想象成 SQL 中的 GROUP BY 子句和各種聚合函數(COUNT, SUM, AVG, MIN, MAX)的組合,但 Elasticsearch 的聚合功能遠比 SQL 更加靈活和強大。

本文將帶你深入了解 Elasticsearch 7.10 版本中聚合查詢的基礎知識。通過本文,你將學習到:

  • 聚合查詢的基本概念和工作原理。
  • 三種核心的聚合類型:指標聚合(Metrics Aggregations)、桶聚合(Bucket Aggregations)和管道聚合(Pipeline Aggregations)。
  • 如何使用各種指標聚合函數(avg, min, max, sum, stats, value_count, cardinality)。
  • 如何使用 terms 聚合進行分組。
  • 如何使用管道聚合對聚合結果進行二次聚合。
  • 通過實戰案例學習如何在實際應用中運用聚合查詢,解決真實的數據分析問題。

二、數據準備 (Data Preparation)

在開始學習聚合查詢之前,我們需要先準備一些示例數據。我們將創建一個名為 product 的索引,并批量導入一些商品數據。

2.1 創建索引 (Create Index)

首先,我們創建一個名為 product 的索引,并定義其 mappings(映射)。Mappings 定義了索引中每個字段的數據類型以及如何進行索引和搜索。

PUT product
{"mappings": {"properties": {"createtime": {"type": "date"},"date": {"type": "date"},"desc": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"lv": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"name": {"type": "text","analyzer": "ik_max_word","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"price": {"type": "long"},"tags": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"type": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}}}}
}

2.2 批量導入數據 (Bulk Import Data)

接下來,我們使用 Elasticsearch 的 _bulk API 來批量導入一些商品數據。_bulk API 可以一次性執行多個索引、更新或刪除操作,效率更高。

POST /product/_bulk
{"index":{"_index": "product"}}
{"name": "小米手機", "desc": "手機中的戰斗機", "price": 3999, "lv": "旗艦機", "type": "手機", "createtime": "2020-10-01T08:00:00Z", "tags": [ "性價比", "發燒", "不卡頓" ]}
{"index":{"_index": "product"}}
{"name": "小米NFC手機", "desc": "支持全功能NFC,手機中的滑翔機", "price": 4999, "lv": "旗艦機", "type": "手機", "createtime": "2020-05-21T08:00:00Z", "tags": [ "性價比", "發燒", "公交卡" ]}
{"index":{"_index": "product"}}
{"name": "NFC手機", "desc": "手機中的轟炸機", "price": 2999, "lv": "高端機", "type": "手機", "createtime": "2020-06-20T08:00:00Z", "tags": [ "性價比", "快充", "門禁卡" ]}
{"index":{"_index": "product"}}
{"name": "小米耳機", "desc": "耳機中的黃燜雞", "price": 999, "lv": "百元機", "type": "耳機", "createtime": "2020-06-23T08:00:00Z", "tags": [ "降噪", "防水", "藍牙" ]}
{"index":{"_index": "product"}}
{"name": "紅米耳機", "desc": "耳機中的肯德基", "price": 399, "type": "耳機", "lv": "百元機", "createtime": "2020-07-20T08:00:00Z", "tags": [ "防火", "低音炮", "聽聲辨位" ]}
{"index":{"_index": "product"}}
{"name": "小米手機10", "desc": "充電賊快掉電更快,超級無敵望遠鏡,高刷電競屏", "price": null, "lv": "旗艦機", "type": "手機", "createtime": "2020-07-27T08:00:00Z", "tags": [ "120HZ刷新率", "120W快充", "120倍變焦" ]}
{"index":{"_index": "product"}}
{"name": "挨炮 SE2", "desc": "除了CPU,一無是處", "price": 3299, "lv": "旗艦機", "type": "手機", "createtime": "2020-07-21T08:00:00Z", "tags": [ "割韭菜", "割韭菜", "割新韭菜" ]}
{"index":{"_index": "product"}}
{"name": "XS Max", "desc": "聽說要出新款12手機了,終于可以換掉手中的4S了", "price": 4399, "lv": "旗艦機", "type": "手機", "createtime": "2020-08-19T08:00:00Z", "tags": [ "5V1A", "4G全網通", "大" ]}
{"index":{"_index": "product"}}
{"name": "小米電視", "desc": "70寸性價比只選,不要一萬八,要不要八千八,只要兩千九百九十八", "price": 2998, "lv": "高端機", "type": "電視", "createtime": "2020-08-16T08:00:00Z", "tags": [ "巨饃", "家庭影院", "游戲" ]}
{"index":{"_index": "product"}}
{"name": "紅米電視", "desc": "我比上邊那個更劃算,我也2998,我也70寸,但是我更好看", "price": 2999, "type": "電視", "lv": "高端機", "createtime": "2020-08-28T08:00:00Z", "tags": [ "大片", "藍光8K", "超薄" ]}
{"index":{"_index": "product"}}
{"name": "紅米電視", "desc": "我比上邊那個更劃算,我也2998,我也70寸,但是我更好看", "price": 2998, "type": "電視", "lv": "高端機", "createtime": "2020-08-28T08:00:00Z", "tags": [ "大片", "藍光8K", "超薄" ]}

代碼解釋:

  • POST /product/_bulk: 使用 _bulk API 向 product 索引發送批量請求。
  • 每一行是一個 JSON 對象,表示一個操作。

現在,我們已經準備好了數據,可以開始學習 Elasticsearch 的聚合查詢了!

三、聚合查詢基礎 (Aggregation Basics)

3.1 什么是聚合查詢?(What are Aggregations?)

聚合查詢(Aggregations)是 Elasticsearch 中一種強大的數據分析功能,它允許你對文檔數據進行各種統計分析。與搜索查詢(返回匹配的文檔)不同,聚合查詢返回的是聚合后的統計結果。

你可以將聚合查詢類比為 SQL 中的 GROUP BY 子句和聚合函數(如 COUNT, SUM, AVG, MIN, MAX)。 例如,你可以使用 SQL 來計算每個部門的平均工資:

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;

Elasticsearch 的聚合查詢提供了類似的功能,但更加靈活和強大。它可以處理更復雜的數據結構和分析場景,并且可以進行多層嵌套的聚合。

3.2 聚合查詢的基本結構 (Basic Aggregation Structure)

聚合查詢的基本語法結構如下:

GET /<index>/_search
{"size": 0,"aggs": {"<aggregation_name>": {"<aggregation_type>": {"<aggregation_parameters>"},"aggs": {"<nested_aggregation_name>": {"<nested_aggregation_type>": {"<nested_aggregation_parameters>"}}}}}
}

解釋:

  • GET /<index>/_search: 這是 Elasticsearch 的搜索 API,我們在這里使用它來執行聚合查詢。
  • "size": 0: 這是一個可選參數。通常,在執行聚合查詢時,我們只關心聚合結果,而不關心具體的文檔內容。"size": 0 表示不返回任何文檔,只返回聚合結果。
  • "aggs" (或 "aggregations"): 這是聚合查詢的頂層關鍵字。所有聚合操作都定義在 aggs 對象中。
  • "<aggregation_name>": 這是你為聚合操作指定的名稱。這個名稱可以是任意的,它將作為聚合結果的一部分返回,方便你識別和引用。例如,你可以將計算平均價格的聚合命名為 "avg_price"
  • "<aggregation_type>": 這是聚合的類型。Elasticsearch 提供了多種聚合類型,每種類型都有不同的功能。常見的聚合類型包括:
    • avg (平均值)
    • min (最小值)
    • max (最大值)
    • sum (總和)
    • terms (詞條聚合)
    • stats (統計信息)
    • 等等…
  • "<aggregation_parameters>": 這是特定于聚合類型的參數。不同的聚合類型有不同的參數。例如,avg 聚合需要指定要計算平均值的字段,terms 聚合需要指定要分組的字段。
  • "aggs": { ... } (在 <aggregation_name> 內部): 這是可選的嵌套聚合。你可以在一個聚合操作中嵌套另一個聚合操作,以實現更復雜的分析。例如,你可以先按產品類別分組,然后在每個類別中計算平均價格。

3.3 聚合類型 (Aggregation Types)

Elasticsearch 提供了三種主要的聚合類型:

  1. Metrics Aggregations (指標聚合): 這類聚合主要用于計算單個數值指標。例如:

    • avg: 計算平均值。
    • min: 計算最小值。
    • max: 計算最大值。
    • sum: 計算總和。
    • stats: 一次性計算多個統計值(avg, min, max, sum, count)。
    • value_count: 計算非空字段的文檔數量。
    • cardinality: 計算字段的不同值的數量(去重)。
  2. Bucket Aggregations (桶聚合): 這類聚合主要用于將文檔分組到不同的“桶”中。每個桶代表一個分組。例如:

    • terms: 按字段值對文檔進行分組。
    • date_histogram: 按日期范圍對文檔進行分組。
    • range: 按自定義數值范圍對文檔進行分組。
    • filter: 根據指定的過濾條件將文檔分到一個桶
    • filters: 根據指定的多個過濾條件將文檔分到多個桶
  3. Pipeline Aggregations (管道聚合): 這類聚合比較特殊,它們不直接操作文檔,而是對其他聚合的結果進行進一步的聚合。例如:

    • min_bucket: 找出包含最小值的桶。
    • max_bucket: 找出包含最大值的桶。
    • avg_bucket: 計算桶的平均值。
    • sum_bucket: 計算桶的總和。
    • stats_bucket: 對桶進行統計分析
    • derivative: 計算導數(例如,計算銷售額的變化率)。

本文將重點介紹這三種聚合類型的基礎用法。接下來,我們將分別深入探討每種聚合類型,并通過示例演示如何在實際應用中使用它們。

四、指標聚合 (Metrics Aggregations)

指標聚合用于計算單個數值指標,例如平均值、最小值、最大值、總和等。這些指標可以幫助你了解數據的整體特征。

4.1 avg (平均值)

avg 聚合用于計算指定字段的平均值。

示例: 計算 product 索引中所有產品的平均價格。

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

代碼解釋:

  • "size": 0: 不返回文檔,只返回聚合結果。
  • "aggs": 聚合查詢的開始。
  • "avg_price": 我們為這個聚合操作指定的名稱。
  • "avg": 指定聚合類型為 avg (平均值)。
  • "field": "price": 指定要計算平均值的字段為 price

結果 (部分):

{..."aggregations": {"avg_price": {"value": 3008.8}}
}

結果中的 "value" 字段顯示了所有產品價格的平均值。

4.2 min (最小值)

min 聚合用于計算指定字段的最小值。

示例: 計算 product 索引中所有產品的最低價格。

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

結果 (部分):

{..."aggregations": {"min_price": {"value": 399.0}}
}

4.3 max (最大值)

max 聚合用于計算指定字段的最大值。

示例: 計算 product 索引中所有產品的最高價格。

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

結果 (部分):

{..."aggregations": {"max_price": {"value": 4999.0}}
}

4.4 sum (總和)

sum 聚合用于計算指定字段的總和。

示例: 計算 product 索引中所有產品的價格總和。

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

結果 (部分):

{..."aggregations": {"sum_price": {"value": 30088.0}}
}

4.5 stats (統計信息)

stats 聚合可以一次性計算多個統計值,包括:

  • count: 文檔數量。
  • min: 最小值。
  • max: 最大值。
  • avg: 平均值。
  • sum: 總和。

示例: 獲取 product 索引中所有產品的價格統計信息。

GET /product/_search
{"size": 0,"aggs": {"price_stats": {"stats": {"field": "price"}}}
}

結果 (部分):

{..."aggregations" : {"statistics" : {"count" : 10,"min" : 399.0,"max" : 4999.0,"avg" : 3008.8,"sum" : 30088.0}}
}

結果中一次性返回了countminmaxavgsum

4.6 value_count (值計數)

value_count 聚合用于計算指定字段的 非空 值的文檔數量。

示例: 計算 product 索引中有多少個文檔具有 price 字段(即有多少個產品有價格信息)。

GET /product/_search
{"size": 0,"aggs": {"price_count": {"value_count": {"field": "price"}}}
}

結果 (部分):

{..."aggregations": {"price_count": {"value": 10}}
}

注意,由于有一個文檔的 price 字段為 null,因此結果為 10,而不是 11。

4.7 cardinality (基數/去重計數)

cardinality 聚合用于計算指定字段的不同值的數量(即去重計數)。

示例: 計算 product 索引中有多少種不同的產品等級 (lv)。

GET /product/_search
{"size": 0,"aggs": {"lv_cardinality": {"cardinality": {"field": "lv.keyword"}}}
}

代碼解釋:

  • "lv_cardinality": 聚合的名稱。
  • "cardinality": 指定聚合類型為 cardinality
  • "field": "lv.keyword": 指定要計算基數的字段為 lv.keyword。 這里使用 .keyword 子字段是因為我們要對原始的、未分詞的 lv 值進行去重計數。

結果 (部分):

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

結果表明,product 索引中有 3 種不同的產品等級。

cardinality 聚合的計算結果是近似的,而不是完全精確的。對于低基數字段(即不同值較少),結果通常是準確的。但對于高基數字段(即不同值非常多),為了提高性能,Elasticsearch 使用了一種稱為 HyperLogLog++ 的算法進行近似計算。你可以通過 precision_threshold 參數來控制精度和內存使用之間的權衡。如果需要完全精確的去重計數,并且數據集較小,可以考慮使用 terms 聚合,并設置一個足夠大的 size 值。但對于大數據集,cardinality 聚合通常是更好的選擇。

五、桶聚合 (Bucket Aggregations)

桶聚合(Bucket Aggregations)用于將文檔分組到不同的“桶”中。每個桶代表一個分組,可以根據不同的條件來創建桶。桶聚合本身不進行統計運算,其主要作用是分組。通常會在桶聚合內嵌套一個或者多個指標聚合,用于統計每個桶內的指標。

5.1 terms (詞條聚合)

terms 聚合是最常用的桶聚合之一。它根據指定字段的值對文檔進行分組,每個不同的字段值都會創建一個桶。

示例:tags.keyword 字段對 product 索引中的產品進行分組,并統計每個標簽下的文檔數量。

GET /product/_search
{"size": 0,"aggs": {"tag_bucket": {"terms": {"field": "tags.keyword","size": 10,"order": {"_count": "desc"}}}}
}

代碼解釋:

  • "size": 0: 不返回文檔,只返回聚合結果。
  • "aggs": 聚合查詢的開始。
  • "tag_bucket": 我們為這個聚合操作指定的名稱。
  • "terms": 指定聚合類型為 terms (詞條聚合)。
  • "field": "tags.keyword": 指定要進行分組的字段為 tags.keyword。使用 .keyword 子字段是因為我們要基于標簽的原始值進行分組,而不是分詞后的結果。
  • "size": 10: 指定返回的桶的最大數量。默認情況下,terms 聚合會返回文檔數量最多的前 10 個桶。
  • "order": { "_count": "desc" }: 指定桶的排序方式。這里按照每個桶中文檔數量 (_count) 的降序 (desc) 進行排序。

結果(部分):

{..."aggregations": {"tag_bucket": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 8,"buckets": [{"key": "性價比","doc_count": 3},{"key": "發燒","doc_count": 2},{"key": "大片","doc_count": 2},{"key": "藍光8K","doc_count": 2},{"key": "超薄","doc_count": 2},{"key": "割韭菜","doc_count": 2},{"key": "120W快充","doc_count": 1},{"key": "120HZ刷新率","doc_count": 1},{"key": "120倍變焦","doc_count": 1},{"key": "4G全網通","doc_count": 1}]}}
}

結果解釋:

  • "buckets": 這是一個數組,包含了根據 tags.keyword 字段值分組后的桶。
  • "key": 每個桶的鍵,即 tags.keyword 字段的值(例如 “性價比”, “發燒”)。
  • "doc_count": 每個桶中的文檔數量。
  • "doc_count_error_upper_bound":由于terms聚合默認情況下返回文檔數量最多的前N個桶,這個值表示因為桶數量限制,沒有被統計到的文檔數量的最大可能誤差值。
  • "sum_other_doc_count": 由于terms聚合默認情況下返回文檔數量最多的前N個桶,這個值表示未返回的其他桶中文檔數量的總和。

size 參數:

size 參數控制返回的桶的數量。 如果你想返回所有桶,可以將 size 設置為一個較大的值(例如,大于字段中不同值的數量)。 但是,請注意,如果字段的基數非常高(即有很多不同的值),返回所有桶可能會消耗大量內存。

order 參數:

order 參數控制桶的排序方式。除了按 _count 排序外,還可以:

  • _key 排序:"order": { "_key": "asc" } (按字段值升序) 或 "order": { "_key": "desc" } (按字段值降序)。
  • 按桶內指標聚合的結果排序(稍后在嵌套聚合中介紹)。

5.2 嵌套桶聚合

在實際應用中,我們經常需要進行多層級的聚合。例如,我們想先按type進行分組,然后統計每個typeprice的平均值。這種情況下我們就需要用到嵌套聚合。

GET /product/_search
{"size": 0,"aggs": {"type_bucket": {"terms": {"field": "type.keyword"},"aggs": {"avg_price": {"avg": {"field": "price"}}}}}
}

代碼解釋:

  • 外層是一個terms聚合, 根據type.keyword字段進行分組。
  • 內層是一個avg聚合, 計算每個分組內price字段的平均值。
  • 內層聚合的結果會作為外層聚合每個桶的一個屬性。

結果(部分):

{..."aggregations": {"type_bucket": {"doc_count_error_upper_bound": 0,"sum_other_doc_count": 0,"buckets": [{"key" : "手機","doc_count" : 6,"avg_price" : {"value" : 3939.0}},{"key" : "耳機","doc_count" : 3,"avg_price" : {"value" : 1465.3333333333333}},{"key" : "電視","doc_count" : 2,"avg_price" : {"value" : 2998.5}}]}}
}

結果解釋:

  • "buckets": 這是一個數組,包含了根據 type.keyword 字段值分組后的桶。
  • "key": 每個桶的鍵,即 type.keyword 字段的值(例如 “手機”, “耳機”)。
  • "doc_count": 每個桶中的文檔數量。
  • "avg_price": 每個桶中嵌套聚合的結果, 即該類型商品的平均價格。

通過嵌套聚合,我們可以輕松實現多層級的數據分析。我們可以根據需求自由組合不同的聚合類型,構建出非常復雜的聚合查詢。

六、管道聚合 (Pipeline Aggregations)

管道聚合(Pipeline Aggregations)是一種特殊的聚合類型。它們不像指標聚合和桶聚合那樣直接操作文檔,而是對其他聚合的結果進行進一步的聚合。這就像在數據處理流程中添加了一個額外的“管道”,對上游聚合的輸出進行處理。

6.1 什么是管道聚合?

管道聚合的核心思想是:輸入是另一個聚合(或多個聚合)的輸出,而不是文檔本身。這使得我們可以進行諸如以下操作:

  • 找出平均價格最低的產品類別。
  • 計算每個月銷售額的總和,然后找出銷售額最高的月份。
  • 計算某個指標的導數或移動平均值。

管道聚合的關鍵參數是 buckets_path,它用于指定要作為輸入的聚合的路徑。

6.2 min_bucket (最小桶)

min_bucket 管道聚合用于找出包含最小值的桶。

示例: 找出平均價格最低的產品分類(基于之前嵌套聚合的結果)。

GET /product/_search
{"size": 0,"aggs": {"type_bucket": {"terms": {"field": "type.keyword"},"aggs": {"avg_price": {"avg": {"field": "price"}}}},"min_avg_price_bucket": {"min_bucket": {"buckets_path": "type_bucket>avg_price"}}}
}

代碼解釋:

  • "type_bucket": 這是一個 terms 聚合,按產品類型 (type.keyword) 分組。
  • "avg_price": 這是一個嵌套的 avg 聚合,計算每個產品類型的平均價格。
  • "min_avg_price_bucket": 這是我們定義的管道聚合的名稱。
  • "min_bucket": 指定聚合類型為 min_bucket
  • "buckets_path": "type_bucket>avg_price": 這是 buckets_path 參數,它指定了要處理的聚合路徑。
    • type_bucket: 表示外層的 terms 聚合。
    • >: 表示嵌套關系。
    • avg_price: 表示內層的 avg 聚合。
    • 所以,"type_bucket>avg_price" 表示我們要找到 type_bucket 聚合中,avg_price 聚合結果最小的那個桶。

結果(部分):

{..."aggregations": {"type_bucket": {... // 省略了 type_bucket 的詳細結果},"min_avg_price_bucket": {"value": 1465.3333333333333,"keys": ["耳機"]}}
}

結果解釋:

  • "min_avg_price_bucket": 管道聚合的結果。
  • "value": 最小值 (最低的平均價格)。
  • "keys": 取得最小值的桶的key值數組, 在本例中, 平均價格最低的分類是 “耳機”。

6.3 其他管道聚合

除了 min_bucket 之外,ElasticSearch 還提供了其他幾種管道聚合:

  • max_bucket: 找出包含最大值的桶。用法與min_bucket類似, 只是找出最大值。
  • avg_bucket: 計算所有桶中某個指標的平均值。
  • sum_bucket: 計算所有桶中某個指標的總和。
  • stats_bucket:一次性計算多個統計值, 類似于stats指標聚合, 但是stats_bucket是作用于桶聚合的結果之上。
  • derivative: 計算導數(例如,計算銷售額的變化率)。
  • moving_avg: 計算移動平均值(例如,計算過去 7 天的平均銷售額)。
  • bucket_script: 使用腳本對桶的指標進行自定義計算。
  • bucket_selector: 根據腳本過濾桶。
  • bucket_sort: 對桶進行排序。

這些管道聚合提供了更高級的數據分析功能。你可以在 ElasticSearch 的官方文檔中找到關于它們的詳細信息。

七、實戰案例 (Practical Examples)

現在,讓我們通過幾個更貼近實際應用的示例,來展示如何組合不同類型的聚合,以解決真實的數據分析問題。

案例 1:統計每個產品類別中,價格最高的產品的價格,并按最高價格降序排列

這個案例結合了 terms 桶聚合、max 指標聚合和排序。

GET product/_search
{"size": 0, "aggs": {"type_bucket": {"terms": {"field": "type.keyword","order": {"max_price": "desc"}},"aggs": {"max_price": {"max": {"field": "price"}}}}}
}

代碼解釋:

  • "type_buckets": terms 聚合,按 type.keyword 字段(產品類型)分組。
  • "order": { "max_price": "desc" }: 按嵌套的 max_price 聚合的結果(即每個類別中的最高價格)進行降序排序。
  • "max_price": 嵌套的 max 聚合,計算每個類別中的最高價格。

結果(部分):

{..."aggregations": {"type_buckets": {..."buckets": [{"key" : "手機","doc_count" : 6,"max_price" : {"value" : 4999.0}},{"key" : "電視","doc_count" : 2,"max_price" : {"value" : 2999.0}},{"key" : "耳機","doc_count" : 3,"max_price" : {"value" : 2998.0}}]}}
}

案例 2:找出每個月銷售額最高的日期

這個案例結合了 date_histogram 桶聚合、sum 指標聚合和 max_bucket 管道聚合。

GET /product/_search
{"size": 0,"aggs": {"sales_per_month": {"date_histogram": {"field": "createtime","calendar_interval": "month"},"aggs": {"sales_per_day": {"date_histogram": {"field": "createtime","calendar_interval": "day"},"aggs": {"daily_sales": {"sum": {"field": "price"}}}},"max_daily_sales": {"max_bucket": {"buckets_path": "sales_per_day>daily_sales"}}}}}
}

代碼解釋:

  1. sales_per_month (外層 date_histogram):

    • 按月對文檔進行分組("calendar_interval": "month")。
    • field: “createtime”
  2. sales_per_day (內層 date_histogram):

    • 在每個月的桶內,再按天對文檔進行分組("calendar_interval": "day")。
    • field: “createtime”
  3. daily_sales (指標聚合):

    • 在每個天的桶內,計算當天的銷售總額("sum": { "field": "price" })。
  4. max_daily_sales (管道聚合):

    • 使用 max_bucket 管道聚合。
    • "buckets_path": "sales_per_day>daily_sales": 找出每個月內,daily_sales (銷售總額) 最高的那個 sales_per_day (天) 桶。

結果 (部分):

{..."aggregations": {"sales_per_month": {"buckets": [{"key_as_string": "2020-05-01T00:00:00.000Z","key": 1588291200000,"doc_count": 1,"sales_per_day": {...},"max_daily_sales": {"value": 4999.0,"keys": ["2020-05-21T00:00:00.000Z"]}},{"key_as_string": "2020-06-01T00:00:00.000Z","key": 1590969600000,"doc_count": 2,"sales_per_day": {...},"max_daily_sales": {"value": 2999.0,"keys": ["2020-06-20T00:00:00.000Z"]}},...]}}
}

結果顯示, 對于每個月, 銷售額最高的那一天的日期和銷售額都被找了出來. 例如, 在2020年5月, 銷售額最高的那一天是2020-05-21, 銷售額是4999.

這兩個案例展示了如何將不同類型的聚合組合起來,以解決更復雜的數據分析問題。 ElasticSearch 聚合的強大之處在于其靈活性和可組合性,你可以根據自己的需求設計出各種各樣的聚合查詢。\

八、總結 (Conclusion)

在本教程中,我們深入探討了 Elasticsearch 7.10 中聚合查詢的基礎知識。聚合查詢是 Elasticsearch 中進行數據分析的強大工具,它能夠幫助你從海量數據中提取出有價值的統計信息和洞察。

我們學習了:

  • 聚合查詢的基本概念和結構: 了解了聚合查詢與搜索查詢的區別,以及聚合查詢的基本 JSON 結構。
  • 三種核心的聚合類型:
    • 指標聚合 (Metrics Aggregations): 用于計算單個數值指標,如平均值、最小值、最大值、總和、去重計數等。
    • 桶聚合 (Bucket Aggregations): 用于將文檔分組到不同的桶中,如按字段值分組、按日期范圍分組等。
    • 管道聚合 (Pipeline Aggregations): 用于對其他聚合的結果進行進一步的聚合,如找出最大值、最小值、計算導數等。
  • 各種常用的聚合函數: avg, min, max, sum, stats, value_count, cardinality, terms, min_bucket, max_bucket 等。
  • 如何使用嵌套聚合: 將不同類型的聚合組合起來,實現更復雜的數據分析。
  • 實戰案例: 通過兩個實際案例,展示了如何運用聚合查詢解決真實的數據分析問題。

Elasticsearch 的聚合功能遠不止于此。本文只是一個入門指南,涵蓋了最基礎和最常用的部分。要充分發揮 Elasticsearch 聚合的威力,你需要不斷學習和實踐,探索更高級的聚合類型和用法。

進一步學習的建議:

  • 閱讀 Elasticsearch 官方文檔: 官方文檔是學習 ElasticSearch 的最佳資源。關于聚合的詳細文檔,請參考
  • 嘗試更多的聚合類型: 除了本文介紹的聚合類型外,ElasticSearch 還提供了許多其他聚合類型,如 date_histogramrangefiltersgeo_distancepercentilestop_hits 等等。
  • 練習、練習、再練習: 最好的學習方法就是實踐。嘗試使用不同的數據集和不同的聚合組合,來解決各種數據分析問題。

希望本文能幫助你入門 Elasticsearch 聚合查詢。祝你在數據分析的道路上不斷進步!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896889.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896889.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896889.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Microsoft.Office.Interop.Excel 的簡單操作

Microsoft.Office.Interop.Excel 的簡單操作 1、安裝 Microsoft.Office.Interop.Excel2、聲明引用 Microsoft.Office.Interop.Excel3、簡單的新建 EXCEL 操作代碼4、將 DataGridView 表數據寫到 EXCEL 操作代碼5、將 EXCEL 表數據讀取到 C# 數據表 DataTable 操作代碼 1、安裝 …

LLM 對話框組件 | 字節青訓營前端開發項目

系統介紹 LLM對話框項目系統介紹 一、項目概述 選題背景隨著人工智能技術的飛速發展,自然語言處理(NLP)領域取得了顯著進展,其中對話系統(Dialog System)作為NLP的重要應用方向,正逐漸滲透到人們的日常生活中。從智能客服到語音助手,從智能家居到在線教育,對話系統以…

k8s命名空間和資源配額

在現代的云計算環境中&#xff0c;容器化技術已成為主流。而 Kubernetes&#xff08;簡稱 k8s&#xff09;作為一項開源的容器編排系統&#xff0c;廣泛應用于各類場景。本文將詳細介紹關于 k8s 中的命名空間和資源配額&#xff0c;幫助你更好地理解和管理你的集群資源。 k8s …

從統計學視角看機器學習的訓練與推理

從統計學視角看機器學習的訓練與推理 目錄 引言&#xff1a;統計學與機器學習的奇妙緣分訓練與推理&#xff1a;你得先學會“看數據”再“用數據”最大似然估計&#xff08;MLE&#xff09;&#xff1a;從直覺到數學證明 3.1 伯努利分布的MLE3.2 單變量高斯分布的MLE3.3 多元…

AI賦能企業協作4-NL2Sql技術路線

1.1 對話即服務的一點思考 在數智化轉型的過程中&#xff0c;基于即時通信&#xff08;IM&#xff09;的協作平臺正悄然成為企業智能化轉型的“新基建”。協作平臺天然具備高頻交互、實時協同和場景化落地的特性&#xff0c;仿佛是為對話式AI量身定制的試驗場——員工在熟悉的聊…

批量提取 Word 文檔中的頁面

如何將 Word 文檔中的頁面提取出來形成一個新的文檔呢&#xff1f;比如將 Word 文檔中的第一頁提取出來、將 Word 文檔中的最后一頁提取出來、再或者將 Word 文檔中的中間幾頁提取出來等等。人工的處理肯定非常的麻煩&#xff0c;需要新建 Word 文檔&#xff0c;然后將內容復制…

Sqlserver安全篇之_啟用TLS即配置SQL Server 數據庫引擎以加密連接

官方文檔 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/configure-sql-server-encryption?viewsql-server-ver16 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/manage-certificates?viewsql-server-ver15&pre…

多鏡頭視頻生成、機器人抓取、擴散模型個性化 | Big Model weekly第58期

點擊藍字 關注我們 AI TIME歡迎每一位AI愛好者的加入&#xff01; 01 GLM-4-Voice: Towards Intelligent and Human-Like End-to-End Spoken Chatbot 本文介紹了一種名為GLM-4-Voice的智能且類人化的端到端語音聊天機器人。它支持中文和英文&#xff0c;能夠進行實時語音對話&a…

基于 Rust 與 GBT32960 規范的編解碼層

根據架構設計&#xff0c;實現編解碼層的代碼設計 Cargo.toml 加入二進制序列化支持 # 序列化支持 ... bincode "1.3" # 添加二進制序列化支持 bytes-utils "0.1" # 添加字節處理工具 開始編碼 錯誤處理&#xff08;error.rs&#x…

MOM成功實施分享(七)電力電容制造MOM工藝分析與解決方案(第一部分)

聲明&#xff1a;文章僅用于交流學習&#xff0c;不用于商業項目實施&#xff0c;圖片來源于網絡&#xff0c;如有侵犯權利&#xff0c;請聯系作者及時刪除。 本方案旨在對電力電容&#xff08;PEC和PQM型號&#xff09;制造工藝深度分析&#xff0c;結合管理要求設計MOM相關功…

FPGA開發,使用Deepseek V3還是R1(1):應用場景

以下都是Deepseek生成的答案 FPGA開發&#xff0c;使用Deepseek V3還是R1&#xff08;1&#xff09;&#xff1a;應用場景 FPGA開發&#xff0c;使用Deepseek V3還是R1&#xff08;2&#xff09;&#xff1a;V3和R1的區別 FPGA開發&#xff0c;使用Deepseek V3還是R1&#x…

JavaWeb后端基礎(3)

原打算把Mysql操作數據庫的一些知識寫進去&#xff0c;但是感覺沒必要&#xff0c;要是現在會的都是簡單的增刪改查&#xff0c;所以&#xff0c;這一篇&#xff0c;我直接從java操作數據庫開始寫&#xff0c;所以這一篇大致就是記一下JDBC、MyBatis、以及SpringBoot的配置文件…

Pytorch實現之SRGAN+CBAM的結構設計

簡介 簡介:在SRGAN的殘差連接中加入了CBAM注意力機制,同時設計了四類損失來訓練。 論文題目:Super-resolution Generative Adversarial Networks Based on Attention Model(基于注意力模型的超分辨率生成對抗網絡) 會議:2020 IEEE第六屆計算機與通信國際會議 摘要:基…

移動端國際化翻譯同步解決方案-V3

1.前言 因為軟件出海&#xff0c;從在上上家公司就開始做翻譯系統&#xff0c;到目前為止已經出了兩個比較大的版本了&#xff0c;各個版本解決的痛點如下&#xff1a; V1版本&#xff1a; 主要針對的是AndroidiOS翻譯不一致和翻譯內容管理麻煩的問題&#xff0c;通過這個工具…

2.css簡介

什么是css&#xff1a; CSS (Cascading Style Sheets&#xff0c;層疊樣式表&#xff09;&#xff0c;是一種用來為結構化文檔&#xff08;如 HTML 文檔或 XML 應用&#xff09;添加樣式&#xff08;字體、間距和顏色等&#xff09;的計算機語言&#xff0c;CSS 文件擴展名為 .…

機器人學習模擬框架 robosuite (3) 機器人控制代碼示例

Robosuite框架是一個用于機器人模擬和控制的強大工具&#xff0c;支持多種類型的機器人。 官方文檔&#xff1a;Overview — robosuite 1.5 documentation 開源地址&#xff1a;https://github.com/ARISE-Initiative/robosuite 目錄 1、通過鍵盤或SpaceMouse遠程控制機器人…

可終身授權的外國工具,不限次數使用!PDF轉CAD的軟件

最近有不少朋友問我有沒有好用的CAD轉換工具&#xff0c;今天就來給大家分享兩款超實用的小軟件&#xff0c;希望能幫到大家。 第一款軟件是一款國外開發的&#xff0c;它專門用來把PDF文件轉換成CAD格式&#xff0c;特別方便。 這款軟件的操作非常簡單&#xff0c;打開后無需安…

Ubuntu系統上部署Node.js項目的完整流程

以下是在Ubuntu系統上部署Node.js項目的完整流程&#xff0c;分為系統初始化、環境配置、項目部署三個部分&#xff1a; 一、系統初始化 & 環境準備 bash # 1. 更新系統軟件包 sudo apt update && sudo apt upgrade -y# 2. 安裝基礎工具 sudo apt install -y buil…

Android內存優化指南:從數據結構到5R法則的全面策略

目錄 一、APP 內存限制 二、內存的三大問題 2.1、內存抖動(Memory Churn) 2.1.1 頻繁創建短生命周期對象 2.1.2 系統API或第三方庫的不合理使用 2.1.3 Handler使用不當 2.2、內存泄漏(Memory Leak) 2.2.1 靜態變量持有Activity或Context引用 2.2.2 未取消的回調或…

ffmpeg源碼編譯支持cuda

1.安裝cuda CUDA Toolkit 11.3 Downloads | NVIDIA Developer 在選擇組件的時候&#xff0c;將CUDA中的Nsight VSE和Visual Studio Integration取消勾選 不然會安裝失敗 2.編譯ffmpeg 把cuda編譯宏定義開啟&#xff0c;再編譯avcodec 3.編譯livavutil報錯struct "Cuda…