ElasticSearch 聚合自定義排序

        ElasticSearch 在使用聚合功能的時候,排序的默認規則是依據命中的文檔數量來做一個倒序獲取;但有些統計場中並不是命中的文檔數量越多其統計的結果就越大, 因爲很多時候聚合的數據是文檔中的其他字段信息。

以上是一個按國家分類的聚合統計,統計的字段分別是銷售金額和銷售數量,由於每個訂單存在的數量和金額都不是對等的,這時候就存在一個問題不能依據訂單數量來作爲排序依據。

        既然是金額當然是需要按照金額量來排序,不是訂單數量。所以在定義 aggs 聚合的情況還要再多定義一個排序聚合節點來做一個排序輸出。

POST /sales/_search
{
  "size": 0,
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "total_sales": {
          "sum": {
            "field": "price"
          }
        },
        "sales_bucket_sort": {
          "bucket_sort": {
            "sort": [
              { "total_sales": { "order": "desc" } } 
            ],
            "size": 3                                
          }
        }
      }
    }
  }
}

以上是官方文檔描述的示例,對月份進行一個聚合分類,並對相應的 price 字段進行一個求和,最後針對聚合後的總價進行排序。在這裏需要說明的是排序描述那部分,sales_bucket_sort 是 aggs 排序的一個子集,這個名稱是可以隨意定義的;接下來的 bucket_sort 則是固定的,內部大部分內容也是固定主要關注的是 total_sales, 它是之前彙總的一個 aggs 子集名稱。

        接下來看回真實應用場是怎麼做的

{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "CreateTime": {
              "gte": "2021-01-01T00:00:00",
              "lte": "2021-03-25T23:59:59"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "Year_group": {
      "aggs": {
        "sum_quantity": {
          "sum": {
            "field": "Quantity"
          }
        },
        "sum_total": {
          "sum": {
            "field": "Total"
          }
        },
        "query_bucket_sort": {
          "bucket_sort": {
            "sort": [
              {
                "sum_total": {
                  "order": "desc"
                }
              }
            ],
            "size": 10,
            "from": 0
          }
        }
      },
      "terms": {
        "field": "Tag",
        "include": "國家.*",
        "size": 10,
        "shard_size": 400
      }
    }
  }
}

以上示例是根據國家標籤進行一個分類彙總,然後對 total 字段進行彙總排序輸出。在這裏需要關注一個地方是頂層 aggs 的 size 和子層排序的 size 要對應好,如果只設置頂層的 size 最終排序得到的結果可以會少了,因爲 ElasticSearch 默認對反回的數量都做了限制。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/A2HmjnJCaxniNbTZNGYq4Q