1. 程式人生 > >ElasticSearch學習筆記之二十四 桶聚合續

ElasticSearch學習筆記之二十四 桶聚合續

ElasticSearch學習筆記之二十四 桶聚合續

Date Range Aggregation(時間範圍聚合)

Date Range Aggregation是一個專用於時間型別資料的範圍聚合。它和 range aggregation 主要區別在與fromto 的值可以用日期表示式, 也可以指定返回體中的 fromto 的格式。注意,聚合的每個範圍會包含from但是排除to
例如:

POST /sales/_search?size=0
{
    "aggs": {
        "range":
{ "date_range": { "field": "date", "format": "MM-yyy", "ranges": [ { "to": "now-10M/M" }, { "from": "now-10M/M" } ] } } } }

說明:現在減去10個月,並跳轉到月份的開始時間。

在上面的例子裡, 我們建立了2個範圍分組,第一個會包含10個月之前所有的文件,第二個會包含10個月之前之後的所有文件。

響應如下:

{
    ...
    "aggregations": {
        "range": {
            "buckets": [
                {
                    "to": 1.4436576E12,
                    "to_as_string": "10-2015",
                    "doc_count": 7,
                    "key": "*-10-2015"
                },
                {
                    "from": 1.4436576E12,
                    "from_as_string": "10-2015",
                    "doc_count": 0,
                    "key": "10-2015-*"
                }
            ]
        }
    }
}

Missing Values

missing引數用於定義沒有值的文件應該怎麼處理。預設情況,它們會被忽視掉,當然也可以當作有值來處理 我們需要在對映中為欄位先指明預設值。

POST /sales/_search?size=0
{
  "aggs": {
      "range": {
          "date_range": {
              "field": "date",
              "missing": "1976/11/30",
              "ranges": [
                 {
                   "key": "Older",
                   "to": "2016/02/01"
                 }, 
                 {
                   "key": "Newer",
                   "from": "2016/02/01",
                   "to" : "now/d"
                 }
             ]
         }
     }
  }
}

文件中date 欄位取值為空的會有"1899-12-31"預設值,然後會被劃分到"Older"分組 。

Date Format/Pattern

注意
資訊源於JodaDate

所有ASCII字母保留為格式表示式字母,其定義如下:

Symbol Meaning Presentation Examples
G era text AD
C century of era (>=0) number 20
Y year of era (>=0) year 1996
x weekyear year 1996
w week of weekyear number 27
e day of week number 2
E day of week text Tuesday; Tue
y year year 1996
D day of year number 189
M month of year month July; Jul; 07
d day of month number 10
a halfday of day text PM
K hour of halfday (0~11) number 0
h clockhour of halfday (1~12) number 12
H hour of day (0~23) number 0
k clockhour of day (1~24) number 24
m minute of hour number 30
s second of minute number 55
S fraction of second number 978
z time zone text Pacific Standard Time; PST
Z time zone offset/id zone -0800; -08:00; America/Los_Angeles
escape for text delimiter ‘’

表示式字母的數量決定了格式。

XX 說明
Text 如果表示式字母的數目是4或更多,則使用完整的形式;否則,如果可用的話,可以使用短或縮寫形式。
Number 數字的最小表示。
Year 年份和週歲欄位的數字表示是專門處理的。例如,如果Y的計數為2,則年將顯示為本世紀的零基年,這是兩位數。
Month 3個或者以上使用text 否則使用number
Zone Z輸出沒有冒號偏移,ZZ用冒號、ZZZ或更多的輸出輸出zone id.
Zone names 無法解析時區名稱(Z)。

表示式中的任何字元不在[A.Z]和[A.Z]的範圍內,將被視為引用文字。例如, :, ., ’ , '# and ? 將出現在生成的時間文字中,即使它們不包含在單引號中。

Time zone in date range aggregations

time_zone 引數可以把日期的時區轉換為UTC

時區可以指定為ISO 8601 UTC偏移量(例如+01:00或-08:00),或者指定為來自TZ資料庫的http://www.joda.or g/joda-time/time zones.html[Zone id]之一。

time_zone 引數也可以應用於日期表示式中。作為一個例子,在CET時區開始一天的迴圈,你可以做以下事情:

POST /sales/_search?size=0
{
   "aggs": {
       "range": {
           "date_range": {
               "field": "date",
               "time_zone": "CET",
               "ranges": [
                  { "to": "2016/02/01" }, 
                  { "from": "2016/02/01", "to" : "now/d" },
                  { "from": "now/d" }
              ]
          }
      }
   }
}

日期將被轉換為 2016-02-15T00:00:00.000+01:00.

now/d 被四捨五入為 CET時區一天的開始。

Keyed Response

設定 keyedtrue 會將每個分組和一個獨一無二的key關聯並將返回作為hash返回而不是array:

POST /sales/_search?size=0
{
    "aggs": {
        "range": {
            "date_range": {
                "field": "date",
                "format": "MM-yyy",
                "ranges": [
                    { "to": "now-10M/M" },
                    { "from": "now-10M/M" }
                ],
                "keyed": true
            }
        }
    }
}

響應如下:

{
    ...
    "aggregations": {
        "range": {
            "buckets": {
                "*-10-2015": {
                    "to": 1.4436576E12,
                    "to_as_string": "10-2015",
                    "doc_count": 7
                },
                "10-2015-*": {
                    "from": 1.4436576E12,
                    "from_as_string": "10-2015",
                    "doc_count": 0
                }
            }
        }
    }
}

也支援為每個範圍自定義key:

POST /sales/_search?size=0
{
    "aggs": {
        "range": {
            "date_range": {
                "field": "date",
                "format": "MM-yyy",
                "ranges": [
                    { "from": "01-2015",  "to": "03-2015", "key": "quarter_01" },
                    { "from": "03-2015", "to": "06-2015", "key": "quarter_02" }
                ],
                "keyed": true
            }
        }
    }
}

響應如下:

{
    ...
    "aggregations": {
        "range": {
            "buckets": {
                "quarter_01": {
                    "from": 1.4200704E12,
                    "from_as_string": "01-2015",
                    "to": 1.425168E12,
                    "to_as_string": "03-2015",
                    "doc_count": 5
                },
                "quarter_02": {
                    "from": 1.425168E12,
                    "from_as_string": "03-2015",
                    "to": 1.4331168E12,
                    "to_as_string": "06-2015",
                    "doc_count": 2
                }
            }
        }
    }
}

Filter Aggregation(過濾聚合)

Filter Aggregation是一個在當前索引中過濾所有滿足匹配條件文件的單分組聚合。通常用於從當前聚合得到一個具體的文件集。

例如:

POST /sales/_search?size=0
{
    "aggs" : {
        "t_shirts" : {
            "filter" : { "term": { "type": "t-shirt" } },
            "aggs" : {
                "avg_price" : { "avg" : { "field" : "price" } }
            }
        }
    }
}

在上面的例子我們計算了 t-shirt產品的平均價格.
響應如下:

{
    ...
    "aggregations" : {
        "t_shirts" : {
            "doc_count" : 3,
            "avg_price" : { "value" : 128.33333333333334 }
        }
    }
}

Filters Aggregation(多重過濾聚合)

Filters Aggregation是一個多分組聚合,每個分組關聯一個過濾條件,並收集所有滿足自身過濾條件的文件。

例如:

PUT /logs/_doc/_bulk?refresh
{ "index" : { "_id" : 1 } }
{ "body" : "warning: page could not be rendered" }
{ "index" : { "_id" : 2 } }
{ "body" : "authentication error" }
{ "index" : { "_id" : 3 } }
{ "body" : "warning: connection timed out" }
GET logs/_search
{
  "size": 0,
  "aggs" : {
    "messages" : {
      "filters" : {
        "filters" : {
          "errors" :   { "match" : { "body" : "error"   }},
          "warnings" : { "match" : { "body" : "warning" }}
        }
      }
    }
  }
}

上面的案例我們分析日誌資訊,聚合會建立2個關於日誌資料的分組,一個包含錯誤資訊,一個包含警告資訊。
響應如下:

{
  "took": 9,
  "timed_out": false,
  "_shards": ...,
  "hits": ...,
  "aggregations": {
    "messages": {
      "buckets": {
        "errors": {
          "doc_count": 1
        },
        "warnings": {
          "doc_count": 2
        }
      }
    }
  }
}

Anonymous filters(匿名過濾)

filters 欄位可以作為filters過濾陣列, 如下:

GET logs/_search
{
  "size": 0,
  "aggs" : {
    "messages" : {
      "filters" : {
        "filters" : [
          { "match" : { "body" : "error"   }},
          { "match" : { "body" : "warning" }}
        ]
      }
    }
  }
}

過濾陣列返回的分組和請求一致. 響應如下:

{
  "took": 4,
  "timed_out": false,
  "_shards": ...,
  "hits": ...,
  "aggregations": {
    "messages": {
      "buckets": [
        {
          "doc_count": 1
        },
        {
          "doc_count": 2
        }
      ]
    }
  }
}

Other Bucket(其他分組)

other_bucket 屬性可以在響應中新增一個分組,又來收集所有沒有任何匹配的文件:

取值 說明
false 不做其他分組操縱
true 返回其他分組,如果有命名過濾聚合,呢麼預設這個分組會被命名為_other_,如果是匿名聚合將作為做後一個分組返回

other_bucket_key 引數可以用來為其他分組命名而不是預設的_other_ . 設定這個屬性需要設定_bucket 引數為 true.

下面是一個其他分組命名為other_messages的案例。

PUT logs/_doc/4?refresh
{
  "body": "info: user Bob logged out"
}
GET logs/_search
{
  "size": 0,
  "aggs" : {
    "messages" : {
      "filters" : {
        "other_bucket_key": "other_messages",
        "filters" : {
          "errors" :   { "match" : { "body" : "error"   }},
          "warnings" : { "match" : { "body" : "warning" }}
        }
      }
    }
  }
}

響應如下

{
  "took": 3,
  "timed_out": false,
  "_shards": ...,
  "hits": ...,
  "aggregations": {
    "messages": {
      "buckets": {
        "errors": {
          "doc_count": 1
        },
        "warnings": {
          "doc_count": 2
        },
        "other_messages": {
          "doc_count": 1
        }
      }
    }
  }
}

Global Aggregation(總體聚合)

Global Aggregation是一個無視檢索條件包含所有文件的單分組聚合。聚合的上下文只受檢索的索引限制不受檢索條件限制。

注意:
Global aggregators 只能作為最頂級的聚合使用,把Global Aggregation潛入其他分組是沒有意義的。

例如:

POST /sales/_search?size=0
{
    "query" : {
        "match" : { "type" : "t-shirt" }
    },
    "aggs" : {
        "all_products" : {
            "global" : {},  #global aggregation有一個空的請求體
            "aggs" : { #子聚合包含在global aggregation中
                "avg_price" : { "avg" : { "field" : "price" } }
            }
        },
        "t_shirts": { "avg" : { "field" : "price" } }
    }
}

上面的案例展示了怎麼在無視查詢條件下對所有的文件執行聚合操作(例如avg_price),在我們的案例中我們計算所有產品的平均價格而不是t_shirts

結果如下

{
    ...
    "aggregations" : {
        "all_products" : {
            "doc_count" : 7, 
            "avg_price" : {
                "value" : 140.71428571428572 
            }
        },
        "t_shirts": {
            "value" : 128.33333333333334 
        }
    }
}

Missing Aggregation(空值聚合)

Missing Aggregation是一個對於文件集中對所有確實欄位值或者欄位值被設定為null的文件建立一個分組的單分組聚合。這個聚合通常和其他欄位資料分組聚合一起使用,例如範圍聚合,返回由於缺少欄位值無法放入任何分組的文件集。

例如

POST /sales/_search?size=0
{
    "aggs" : {
        "products_without_a_price" : {
            "missing" : { "field" : "price" }
        }
    }
}

上面的案例中,我們可以得到所有沒有價格的產品
響應如下:

{
    ...
    "aggregations" : {
        "products_without_a_price" : {
            "doc_count" : 00
        }
    }
}