ES 24 - 如何通過Elasticsearch進行聚合檢索 (分組統計)

来源:https://www.cnblogs.com/shoufeng/archive/2019/08/02/11290669.html
-Advertisement-
Play Games

聚合類似於 MySQL 中的 group by 分組, Elasticsearch 支持通過聚合函數 (count、sum、max、min、avg等) 進行統計分析. 具體要如何通過ES進行聚合統計、嵌套聚合等操作呢? 本文通過系列案例, 進行比較詳細的演示, 一起來學習交流吧^_^ ...


目錄

1 普通聚合分析

1.1 直接聚合統計

(1) 計算每個tag下的文檔數量, 請求語法:

GET book_shop/it_book/_search
{
    "size": 0,              // 不顯示命中(hits)的所有文檔信息
    "aggs": {
        "group_by_tags": {  // 聚合結果的名稱, 需要自定義(複製時請去掉此註釋)
            "terms": {
                "field": "tags"
            }
        }
    }
}

(2) 發生錯誤:

說明: 索引book_shop的mapping映射是ES自動創建的, 它把tag解析成了text類型, 在發起對tag的聚合請求後, 將拋出如下錯誤:

{
    "error": {
        "root_cause": [
            {
                "type": "illegal_argument_exception",
                "reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [tags] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
            }
        ],
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "phase": "query",
        "grouped": true,
        "failed_shards": [......]
    },
    "status": 400
}

(3) 錯誤分析:

錯誤信息: Set fielddata=true on [xxxx] ......
錯誤分析: 預設情況下, Elasticsearch 對 text 類型的欄位(field)禁用了 fielddata;
text 類型的欄位在創建索引時會進行分詞處理, 而聚合操作必須基於欄位的原始值進行分析;
所以如果要對 text 類型的欄位進行聚合操作, 就需要存儲其原始值 —— 創建mapping時指定fielddata=true, 以便通過反轉倒排索引(即正排索引)將索引數據載入至記憶體中.

(4) 解決方案一: 對text類型的欄位開啟fielddata屬性:

  • 將要分組統計的text field(即tags)的fielddata設置為true:

    PUT book_shop/_mapping/it_book
    {
        "properties": {
            "tags": {
                "type": "text",
                "fielddata": true
            }
        }
    }
  • 可參考官方文檔進行設置:
    https://www.elastic.co/guide/en/elasticsearch/reference/6.6/fielddata.html. 成功後的結果如下:

    {
      "acknowledged": true
    }
  • 再次統計, 得到的結果如下:

    {
        "took": 153,
        "timed_out": false,
        "_shards": {
            "total": 5,
            "successful": 5,
            "skipped": 0,
            "failed": 0
        },
        "hits": {
            "total": 4,
            "max_score": 0.0,
            "hits": []
        },
        "aggregations": {
            "group_by_tags": {
                "doc_count_error_upper_bound": 0,
                "sum_other_doc_count": 6,
                "buckets": [
                    {
                        "key": "java",
                        "doc_count": 3
                    },
                    {
                        "key": "程",
                        "doc_count": 2
                    },
                    ......
                ]
            }
        }
    }

(5) 解決方法二: 使用內置keyword欄位:

  • 開啟fielddata將占用大量的記憶體.

  • Elasticsearch 5.x 版本開始支持通過text的內置欄位keyword作精確查詢、聚合分析:

    GET shop/it_book/_search
    {
        size": 0,
        "aggs": {
            "group_by_tags": {
                "terms": {
                    "field": "tags.keyword"   // 使用text類型的內置keyword欄位
              }
          }
        }
    }

1.2 先檢索, 再聚合

(1) 統計name中含有“jvm”的圖書中每個tag的文檔數量, 請求語法:

GET book_shop/it_book/_search
{
    "query": {
        "match": { "name": "jvm" }
    }, 
    "aggs": {
        "group_by_tags": {  // 聚合結果的名稱, 需要自定義. 下麵使用內置的keyword欄位: 
            "terms": { "field": "tags.keyword" }
        }
    }
}

(2) 響應結果:

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.64072424,
    "hits" : [
      {
        "_index" : "book_shop",
        "_type" : "it_book",
        "_id" : "2",
        "_score" : 0.64072424,
        "_source" : {
          "name" : "深入理解Java虛擬機:JVM高級特性與最佳實踐",
          "author" : "周志明",
          "category" : "編程語言",
          "desc" : "Java圖書領域公認的經典著作",
          "price" : 79.0,
          "date" : "2013-10-01",
          "publisher" : "機械工業出版社",
          "tags" : [
            "Java",
            "虛擬機",
            "最佳實踐"
          ]
        }
      }
    ]
  },
  "aggregations" : {
    "group_by_tags" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "Java",
          "doc_count" : 1
        },
        {
          "key" : "最佳實踐",
          "doc_count" : 1
        },
        {
          "key" : "虛擬機",
          "doc_count" : 1
        }
      ]
    }
  }
}

1.3 擴展: fielddata和keyword的聚合比較

  • 為某個 text 類型的欄位開啟fielddata欄位後, 聚合分析操作會對這個欄位的所有分詞分別進行聚合, 獲得的結果大多數情況下並不符合我們的需求.

  • 使用keyword內置欄位, 不會對相關的分詞進行聚合, 結果可能更有用.

推薦使用text類型欄位的內置keyword進行聚合操作.

2 嵌套聚合

2.1 先分組, 再聚合統計

(1) 先按tags分組, 再計算每個tag下圖書的平均價格, 請求語法:

GET book_shop/it_book/_search
{
    "size": 0, 
    "aggs": {
        "group_by_tags": {
            "terms": { "field": "tags.keyword" },
            "aggs": {
                "avg_price": {
                    "avg": { "field": "price" }
                }
            }
        }
    }
}

(2) 響應結果:

  "hits" : {
    "total" : 3,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_tags" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "Java",
          "doc_count" : 3,
          "avg_price" : {
            "value" : 102.33333333333333
          }
        },
        {
          "key" : "編程語言",
          "doc_count" : 2,
          "avg_price" : {
            "value" : 114.0
          }
        },
        ......
      ]
    }
  }

2.2 先分組, 再統計, 最後排序

(1) 計算每個tag下圖書的平均價格, 再按平均價格降序排序, 查詢語法:

GET book_shop/it_book/_search
{
    "size": 0,
    "aggs": {
        "all_tags": {
            "terms": {
                "field": "tags.keyword", 
                "order": { "avg_price": "desc" } // 根據下述統計的結果排序
            },
            "aggs": {
                "avg_price": {
                    "avg": { "field": "price" }
                }
            }
        }
    }
}

(2) 響應結果:

與#2.1節內容相似, 區別在於按照價格排序顯示了.

2.3 先分組, 組內再分組, 然後統計、排序

(1) 先按價格區間分組, 組內再按tags分組, 計算每個tags組的平均價格, 查詢語法:

GET book_shop/it_book/_search
{
    "size": 0, 
    "aggs": {
        "group_by_price": {
            "range": {
                "field": "price", 
                "ranges": [
                    { "from": 00,  "to": 100 },
                    { "from": 100, "to": 150 }
                ]
            }, 
            "aggs": {
                "group_by_tags": {
                    "terms": { "field": "tags.keyword" }, 
                    "aggs": {
                        "avg_price": {
                            "avg": { "field": "price" }
                        }
                    }
                }
            }
        }
    }
}

(2) 響應結果:

  "hits" : {
    "total" : 3,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_price" : {
      "buckets" : [
        {
          "key" : "0.0-100.0",    // 區間0.0-100.0
          "from" : 0.0,
          "to" : 100.0,
          "doc_count" : 1,        // 共查找到了3條文檔
          "group_by_tags" : {     // 對tags分組聚合
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Java",
                "doc_count" : 1,
                "avg_price" : {
                  "value" : 79.0
                }
              },
              ......
            ]
          }
        },
        {
          "key" : "100.0-150.0",
          "from" : 100.0,
          "to" : 150.0,
          "doc_count" : 2,
          "group_by_tags" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Java",
                "doc_count" : 2,
                "avg_price" : {
                  "value" : 114.0
                }
              },
              ......
              }
            ]
          }
        }
      ]
    }
  }

版權聲明

作者: 馬瘦風(https://healchow.com)

出處: 博客園 馬瘦風的博客(https://www.cnblogs.com/shoufeng)

感謝閱讀, 如果文章有幫助或啟發到你, 點個[

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 轉載請註明出處: BooTurbo https://www.cnblogs.com/booturbo/p/11287557.html 1、英文的Ubuntu系統,首先要安裝中文語言,在 Settings 裡面選擇 Region & Language,點擊 Manage Installed Langu ...
  • 1. 說明 正在使用的阿裡雲伺服器報了幾個內核漏銅,使用自帶【一鍵修複】需要額外的支付費用,所以嘗試採用升級系統內核的方式來修複漏洞。 1.1 伺服器參數 操作系統:CentOS 7.4 64位 當前內核版本:Linux 3.10.0 1.2 ELRepo ELRepo是一個為Linux提供驅動程式 ...
  • tcpdump採用命令行方式對介面的數據包進行篩選抓取,其豐富特性表現在靈活的表達式上。 不帶任何選項的tcpdump,預設會抓取第一個網路介面,且只有將tcpdump進程終止才會停止抓包。 例如: shell tcpdump nn i eth0 icmp 下麵是詳細的tcpdump用法。 1.1 ...
  • 一、前言 1、之前的文章中介紹瞭如何使用smokeping監控全國各省的網路情況: 2、由於之前的文章中給出的IP列表,會出現不可用的情況,本文更新了自動獲取IP地址列表的腳本 二、環境準備 | 組件 | 版本 | | | | | OS | Ubuntu 16.04.4 LTS | 三、代碼更新日誌 ...
  • awk分析日誌常用高級使用命令方法 分析訪問日誌(Nginx為例) 日誌格式: ...
  • OLAP和OLTP的區別(基礎知識) 聯機分析處理 (OLAP) 的概念最早是由關係資料庫之父E.F.Codd於1993年提出的,他同時提出了關於OLAP的12條準則。OLAP的提出引起了很大的反響,OLAP作為一類產品同聯機事務處理 (OLTP) 明顯區分開來。當今的數據處理大致可以分成兩大類:聯 ...
  • [TOC] "一、SQLite簡介" 最近在使用Python+Flask框架寫項目,使用到了SQLite3資料庫,在這裡總結一下,如果有不正確的地方,煩請指正。 一、SQLite簡介 SQLite 是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統,它包含在一個相對小的C庫中。實現了自給自足的 ...
  • 1、sysbench sysbench是跨平臺的基準測試工具,支持多線程,支持多種資料庫; 主要包括以下幾種測試: cpu性能 磁碟io性能 調度程式性能 記憶體分配及傳輸速度 POSIX線程性能 資料庫性能(OLTP基準測試) 參考: https://www.cnblogs.com/kismetv/ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...