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