Posted at

Elasticsearch2.xのAggregationの概要まとめ

More than 3 years have passed since last update.


目次


  • Aggregation 2.x

  • Metrics Aggregations

  • Bucket Aggregations

  • Pipeline Aggregations

  • まとめ

  • おまけ


Aggregation 2.x

インデックスに対して検索を行うと検索条件に一致したドキュメントの集合「hits」が得られます。hitsに含まれるドキュメントが持つ情報を集計するのがaggregationの機能です。公式のドキュメント(執筆時点で2.1が最新)ではMetrics Aggregations, Bucket Aggregations, Pipeline Aggregationsの3種類に分類されています。

今更ではあるのですが、私はこれまでなんとなく使っていただけだったので全体像をイメージできるようにまとめておこうと思います。


Metrics Aggregations

「それぞれのドキュメントが持つ集計する」というような説明になっています。


  • 値:それぞれのドキュメントのfieldに格納された値、もしくはscriptingによって生成された値

  • 集計:最大値、最小値、合計など、それぞれのaggregationによって異なる

scripted metrics aggregationのドキュメントがそのものズバリなのですが、集計処理というのはMapReduceに相当する処理がされているようです。分散して保持しているデータを集計するので当然ではあるのですが、ドキュメントのlistに対してmap関数、reduce関数を適用する処理であると理解しておくのがわかりやすそうです。


  • 値:document_idからfieldの値(もしくはscriptingの結果)へのmap関数により取得

  • 集計:値を集計するreduce関数


Bucket Aggregations

公式ドキュメントには「値を集計するのではなくbuckets of documentsを作成する」とあります。bucketというのは特定の条件で絞り込まれたドキュメントの集合であり、hits(検索結果のドキュメント集合)の部分集合になります。時系列データをkibanaで可視化している人にはお馴染みのdate histogram aggregationはtimestampなどの値が特定の範囲にあるドキュメントをbucketとして纏めあげています。

bucketを作るだけで集計はまた別になるのですがbucket aggregationに属するaggregationでは基本的にはbucketに含まれるドキュメントの数を返しているようです。

hits(document list) -> bucket list -> doc_count list

bucketがhitsの部分集合であるということは、hitsと同様にbucketに含まれるドキュメントを対象にaggregationを行うこともできるということになります。それがsub aggregationと呼ばれているものになります。

一方、bucket listに対して(bucketを単位として)Map/Reduceの処理を行うのがpipeline aggregationです。


  • bucket内でaggregation:sub aggregation

  • bucket間でaggregation:pipeline aggregation


Pipeline Aggregations

bucket aggregationで得られたbucket listに対してaggregationを行うもので、parent pipeline aggregationsibling pipeline aggregationの2種類があります。

bucket listを受けてもう一度bucket listを返すのがparentで、Reduce処理された値を返すのがsiblingということのようです。


  • parent pipeline aggregation:bucket list -> bucket list

  • sibling pipeline aggregation:bucket list -> value

Elastic{on} Tour Tokyoでもチラっと紹介されていたderivative aggregationはbucket間の増分を算出するsibling pipeline aggregationです。階差数列をイメージするとわかりやすいのですが、数列(bucket list)を受けてまた数列(bucket list)を返す構造になります。

おそらくこの記事で紹介されていたものだと思います。時系列順の距離データderivativea aggregationを使うことで速度(距離の増分)を算出し、さらにもう一度使うことで加速度(速度の増分)を出す、という例でした。

もう1例として、date histogram aggregation > avg aggregationというsub aggregationの結果をmax bucket aggregationに繋いだ場合、指定した値の平均値が最も高い期間(とその値)が得られます。こちらはbucket listを受けて値を返すparent pipeline aggregationです。


まとめ

図解も使用例もない記事になってしまいました。advent calendarの記事ではありますが、できればこれからも加筆していければ良いなと思っています。来年はソースコードを読みながらElasticsearchとLuceneの理解を深めるのが目標です。


[おまけ] Elastic{on} Tour Tokyoの感想を少々


Senseを使おう

大谷さんが説明されていたものですが、あまり使っている人がいなかったようですね。超便利なので使える環境にいるのであればすぐにでも導入しましょう。世界が変わります。


検索の速度について

基調講演を聞いていて、shay氏は検索の速度に強いこだわりがあるのだと感じました。また、Goldman SachsのIan Maclean氏が発表の中で「処理速度が上がったことで、新しいアイデアが生まれた」と言っていたのが印象に残っています。速度というのは量的な変化ではなく、時に質的な変化をもたらすのだということを心に留めておこうと思っています。