ElasticSearch 2 (34) - 信息聚合系列之多值排序


ElasticSearch 2 (34) - 信息聚合系列之多值排序

摘要

多值桶(termshistogramdate_histogram)動態生成很多桶,Elasticsearch 是如何決定這些桶展示給用戶的順序呢?

默認的,桶會根據 doc_count 降序排列,這是一個好的默認行為,因為通常我們想要找到文檔中與查詢條件相關的最大值:售價、人口數量、頻率。但有些時候我們希望能修改這個順序,不同的桶有着不同的處理方式。

版本

elasticsearch版本: elasticsearch-2.x

內容

多值桶(termshistogramdate_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

    按文檔數排序。在 termshistogramdate_histogram 內使用。

  • _term

    按詞項的字符串值的字母順序排序。只在 terms 內使用。

  • _key

    按每個桶的鍵值數值排序(理論上與 _term 類似)。只在 histogramdate_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)動態生成許多桶,無法通過指定一個確定路徑來識別。

目前,只有三個單值桶:filterglobalreverse_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 桶是個單值桶。

參考

elastic.co:
Sorting Multivalue Buckets


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM