15
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ElasticsearchでAggregationの結果に対する絞り込み(SQLのHAVING句)を行う

Last updated at Posted at 2018-05-20

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以上のデータのみに絞り込む場合は以下のようなクエリになります。

SQLのイメージ
SELECT product_name, SUM(count)
FROM product
GROUP BY product_name
HAVING SUM(count) > 50
query
{
  "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"
          }
        }
      }
    }
  }
}
response(aggregations)
{
  "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件以上存在する商品のみに絞り込む場合は以下のようなクエリになります。

SQLのイメージ
SELECT product_name, COUNT(product_name)
FROM product
GROUP BY product_name
HAVING COUNT(product_name) >= 5
query
{
  "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"
          }
        }
      }
    }
  }
}
response(aggregations)
{
  "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
        }
      ]
    }
  }
}
15
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?