ElasticSearch 2 (34) - 信息聚合系列之多值排序
摘要
多值桶(terms
、histogram
和 date_histogram
)動態生成很多桶,Elasticsearch 是如何決定這些桶展示給用戶的順序呢?
默認的,桶會根據 doc_count
降序排列,這是一個好的默認行為,因為通常我們想要找到文檔中與查詢條件相關的最大值:售價、人口數量、頻率。但有些時候我們希望能修改這個順序,不同的桶有着不同的處理方式。
版本
elasticsearch版本: elasticsearch-2.x
內容
多值桶(terms
、histogram
和 date_histogram
)動態生成很多桶,Elasticsearch 是如何決定這些桶展示給用戶的順序呢?
默認的,桶會根據 doc_count
降序排列,這是一個好的默認行為,因為通常我們想要找到文檔中與查詢條件相關的最大值:售價、人口數量、頻率。但有些時候我們希望能修改這個順序,不同的桶有着不同的處理方式。
排序的本質(Intrinsic Sorts)
這些排序模式是桶 固有的 能力:它們操作桶生成的數據,比如 doc_count
。它們共享相同的語法,但是根據使用桶的不同會有些細微差別。
讓我們做一個 terms
聚合但是按 doc_count
值的升序排序:
GET /cars/transactions/_search
{
"size" : 0,
"aggs" : {
"colors" : {
"terms" : {
"field" : "color",
"order": {
"_count" : "asc" #1
}
}
}
}
}
#1 用關鍵字 _count
,我們可以按 doc_count
值的升序排序。
我們為聚合引入了一個 order
對象,它使我們可以根據以下值進行排序:
-
_count
按文檔數排序。在
terms
、histogram
、date_histogram
內使用。 -
_term
按詞項的字符串值的字母順序排序。只在
terms
內使用。 -
_key
按每個桶的鍵值數值排序(理論上與
_term
類似)。只在histogram
和date_histogram
內使用。
按度量排序(Sorting by a Metric)
有時,我們會想基於度量計算的結果值進行排序。在我們的汽車銷售分析儀表盤中,我們可能想按照汽車顏色創建一個銷售條狀圖表,但按照汽車平均售價的升序進行排序。
我們可以增加一個度量,再指定 order
參數引用這個度量即可:
GET /cars/transactions/_search
{
"size" : 0,
"aggs" : {
"colors" : {
"terms" : {
"field" : "color",
"order": {
"avg_price" : "asc" #1
}
},
"aggs": {
"avg_price": {
"avg": {"field": "price"} #2
}
}
}
}
}
#1 計算每個桶的平均售價。
#2 桶按照計算平均值的升序排序。
我們可以采用這種方式用任何度量排序,只需簡單的引用度量的名字。不過有些度量會輸出多個值。extended_stats
度量是一個很好的例子:它輸出好幾個度量值。
如果我們想使用多值度量進行排序,我們只需以關心的度量為關鍵詞使用點式路徑:
GET /cars/transactions/_search
{
"size" : 0,
"aggs" : {
"colors" : {
"terms" : {
"field" : "color",
"order": {
"stats.variance" : "asc" #1
}
},
"aggs": {
"stats": {
"extended_stats": {"field": "price"}
}
}
}
}
}
#1 使用點式標記方式,我們可以對感興趣的度量進行排序。
在上面這個例子中,我們按每個桶的方差來排序,所以售價方差最小的會出現在方差更多之前。
基於“深度”度量排序(Sorting Based on "Deep" Metrics)
在前面的示例中,度量是桶的直接子節點。平均售價是根據每個 term 來計算的。在一定條件下,我們也有可能對更深的度量進行排序,比如孫子桶或從孫桶。
我們可以定義更深的路徑,將度量用尖括號(>
)嵌套起來,像這樣: my_bucket>another_bucket>metric
。
需要提醒的是嵌套路徑上的每個桶都必須是單值的。filter
桶生成一個單值桶:所有與過濾條件匹配的文檔都在桶中。多值桶(如:terms
)動態生成許多桶,無法通過指定一個確定路徑來識別。
目前,只有三個單值桶:filter
、global
和 reverse_nested
。讓我們快速用示例說明,創建一個汽車售價的直方圖,但是按照紅色和綠色(不包括藍色)車各自的方差來排序:
GET /cars/transactions/_search
{
"size" : 0,
"aggs" : {
"colors" : {
"histogram" : {
"field" : "price",
"interval": 20000,
"order": {
"red_green_cars>stats.variance" : "asc" #1
}
},
"aggs": {
"red_green_cars": {
"filter": { "terms": {"color": ["red", "green"]}}, #2
"aggs": {
"stats": {"extended_stats": {"field" : "price"}} #3
}
}
}
}
}
}
#1 按照嵌套度量的方差對桶的直方圖進行排序。
#2 因為我們使用單值過濾器,我們可以使用嵌套排序。
#3 按照生成的度量對統計結果進行排序。
本例中,可以看到我們如何訪問一個嵌套的度量,stats
度量是 red_green_cars
聚合的子節點,而red_green_cars
又是 colors
聚合的子節點。為了根據這個度量排序,我們定義了路徑 red_green_cars>stats.variance
。我們可以這么做,因為 filter
桶是個單值桶。