Bucket Aggregation 桶聚合 ---------group by (上)

Global Aggregation

全局聚合,最頂級的聚合,無法嵌入到其他bucket聚合+

example:

POST /sales/_search?size=0
{
    "query" : {
        "match" : { "type" : "t-shirt" }
    },
    "aggs" : {
        "all_products" : {
            "global" : {}, 
            "aggs" : { 
                "avg_price" : { "avg" : { "field" : "price" } }
            }
        },
        "t_shirts": { "avg" : { "field" : "price" } }
    }
}

result:

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

分析:global 查詢了上下文 所有文檔的 平均價格。avg_price 是爲global 註冊的聚合。

javaApi:

    1. 創建聚合請求

AggregationBuilders
    .global("agg")
    .subAggregation(AggregationBuilders.terms("genders").field("gender"));

    2.分析結果

// sr is here your SearchResponse object
Global agg = sr.getAggregations().get("agg");
agg.getDocCount(); // Doc count

Filter Aggregation

定義當前文檔集上下文中與指定篩選器匹配的所有文檔的單個桶。通常,這將用於將當前聚合上下文縮小到特定的一組文檔。

簡而言之 ,就是先查,再根據查到的再聚合。

example:

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

分析:我們計算了所有t恤類型產品的平均價格。

javaapi:

AggregationBuilders
    .filter("agg", QueryBuilders.termQuery("gender", "male"));

Filters Aggregation

定義一個多桶聚合,其中每個桶與一個過濾器關聯。每個bucket將收集與其關聯的過濾器匹配的所有文檔。

簡而言之,先構建多個過濾器,再根據這些過濾器聚合。應用場景,如果你group by 後面的條件不僅僅是字段,而需要將字段中的各個值,重新分類,定義成不同的類型再group by,可以用這個聚合。

example

PUT /logs/message/_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" }}
        }
      }
    }
  }
}
{
  "took": 9,
  "timed_out": false,
  "_shards": ...,
  "hits": ...,
  "aggregations": {
    "messages": {
      "buckets": {
        "errors": {
          "doc_count": 1
        },
        "warnings": {
          "doc_count": 2
        }
      }
    }
  }
}

javaapi:

      request:

AggregationBuilder aggregation =
    AggregationBuilders
        .filters("agg",
            new FiltersAggregator.KeyedFilter("men", QueryBuilders.termQuery("gender", "male")),
            new FiltersAggregator.KeyedFilter("women", QueryBuilders.termQuery("gender", "female")));

    response:

// sr is here your SearchResponse object
Filters agg = sr.getAggregations().get("agg");

// For each entry
for (Filters.Bucket entry : agg.getBuckets()) {
    String key = entry.getKeyAsString();            // bucket key
    long docCount = entry.getDocCount();            // Doc count
    logger.info("key [{}], doc_count [{}]", key, docCount);
}

 

anonymous filters 匿名 

詳情見官方文檔,就是filter字段可以用過濾器數組,不需要對過濾器命名

other bucket

可以將other_bucket參數設置爲向響應添加一個bucket,該響應將包含與任何給定過濾器不匹配的所有文檔。

PUT logs/message/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
        }
      }
    }
  }
}

Missing Aggregation 缺省聚合

一個基於字段數據的單桶聚合,它爲當前文檔集   中缺少字段值  的所有文檔創建一個桶(實際上,缺少字段 或具有已配置的  空值集)。此聚合器通常 與其他字段 數據桶聚合器(例如範圍)一起使用,以返回由於缺少字段數據值 而無法放在任何其他桶中  的所有文檔的信息。簡而言之,就是可以將 爲空值的數據 放到一個桶中。

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

獲得沒有價格的產品總數,爲0很正常,產品怎麼會沒價格。

javaapi:

AggregationBuilders.missing("agg").field("gender");

分析結果,同上。

Nested Aggregation 嵌套聚合

一種特殊的單桶聚合,支持聚合嵌套文檔。
例如,假設我們有一個產品索引,每個產品都包含分銷商列表——每個分銷商都有自己的產品價格。映射可以是這樣的:

PUT /index
{
  "mappings": {
    "product" : {
        "properties" : {
            "resellers" : { 
                "type" : "nested",
                "properties" : {
                    "name" : { "type" : "text" },
                    "price" : { "type" : "double" }
                }
            }
        }
    }
  }
}
GET /_search
{
    "query" : {
        "match" : { "name" : "led tv" }
    },
    "aggs" : {
        "resellers" : {
            "nested" : {
                "path" : "resellers"
            },
            "aggs" : {
                "min_price" : { "min" : { "field" : "resellers.price" } }
            }
        }
    }
}
{
  ...
  "aggregations": {
    "resellers": {
      "doc_count": 0,
      "min_price": {
        "value": 350
      }
    }
  }
}

正如您在上面看到的,嵌套聚合需要頂層文檔中的嵌套文檔的路徑。然後可以在這些嵌套文檔上定義任何類型的聚合。

聚合將返回可以購買產品的最低價格

javaapi:

AggregationBuilders
    .nested("agg", "resellers");

分析結果同上。

預知後事如何,請看下篇。

官方英文文檔:文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章