Bucket Selector Aggregationを使うことでElasticsearchのAggregationの結果に対する絞り込み、SQLで言うところのHAVING句を実現できます。
環境
Elasticsearch 6.2.4
サンプルデータ
以下のように店名、商品名、個数を持っているデータがいくつか入っています。
{
"market_name": "A八百屋",
"product_name": "にんじん",
"count": 10
},
{
"market_name": "Bスーパー",
"product_name": "りんご"
"count": 10
},
{
"market_name": "Cマーケット",
"product_name": "セロリ"
"count": 5
}
特定の条件を満たす集計結果の絞り込み
集計した合計値が一定の値以上の場合など、特定の条件を満たす集計結果だけに絞りこむ事が出来ます。
例えば商品の個数の合計が50以上のデータのみに絞り込む場合は以下のようなクエリになります。
SELECT product_name, SUM(count)
FROM product
GROUP BY product_name
HAVING SUM(count) > 50
{
"size": 0,
"aggs": {
"product_name_aggs": {
"terms": {
"field": "product_name",
"size": 100
},
"aggs": {
"count_sum": {
"sum": {
"field": "count"
}
},
"count_sum_bucket": {
"bucket_selector": {
"buckets_path": {
"product_count_sum": "count_sum"
},
"script": "params.product_count_sum > 50"
}
}
}
}
}
}
{
"aggregations": {
"product_name_aggs": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "にんじん",
"doc_count": 9,
"count_sum": {
"value": 63
}
}
]
}
}
}
buckets_path
に絞り込み条件の対象となる項目を指定します。
今回はHAVING句のSUM(count)に相当するcount_sum
(自分で命名したAggregation名)を条件指定の対象にしています。
script
には絞り込み条件を記述します。
buckets_path
で指定した値は変数名を利用することで参照できます。
今回はproduct_count_sum
という変数名をつけたので、params.product_count_sum
という形で指定します。
params
は実行したクエリ内の変数を参照する場合に利用する値です。
ちなみに以下のAggregationを使うことでSQLの集計関数を置き換えることが出来ます。
Elasticsearch | SQL |
---|---|
Avg Aggregation | AVG |
Max Aggregation | MAX |
Min Aggregation | MIN |
Sum Aggregation | SUM |
doc_countに対する絞り込み
Aggregationで得られたdoc_count
に対して絞り込みを行いたい場合、buckets_path
に_count
を指定することで実現できます。
(_count
の公式ドキュメント)
例えば商品名で集約した場合に5件以上存在する商品のみに絞り込む場合は以下のようなクエリになります。
SELECT product_name, COUNT(product_name)
FROM product
GROUP BY product_name
HAVING COUNT(product_name) >= 5
{
"size": 0,
"aggs": {
"product_name_aggs": {
"terms": {
"field": "product_name",
"size": 100
},
"aggs": {
"product_name_bucket": {
"bucket_selector": {
"buckets_path": {
"product_count": "_count"
},
"script": "params.product_count >= 5"
}
}
}
}
}
}
{
"aggregations": {
"product_name_aggs": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "にんじん",
"doc_count": 9
},
{
"key": "りんご",
"doc_count": 8
},
{
"key": "白菜",
"doc_count": 5
}
]
}
}
}