Bucket と Metrics を使って、検索ではなくドキュメントの情報を分析できるようです。
Bucket と Metrics はどちらも、Aggregation と言われるものの一部みたいですね。
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
それぞれ単体でも使用できますが、一般的には合わせて使うケースのほうが多そうです。
ドキュメントを Bucket でグループ化し、Metrics で分析を行う、というのが一般的な使い方ではないでしょうか。
ドキュメントの作成
item インデックスに、いくつかドキュメントを保存しました。
PUT item { "mappings": { "properties": { "name": { "type": "text" }, "category": { "type": "keyword" }, "price": { "type": "long" } } } } POST item/_doc { "name": "soba", "category": "noodle", "price": 1000 } POST item/_doc { "name": "ramen", "category": "noodle", "price": 1500 } POST item/_doc { "name": "lettuce", "category": "vegetable", "price": 2000 } POST item/_doc { "name": "bacon", "category": "meat", "price": 2500 }
Buket と Metrics を使って分析してみる
まずは Bucket を使って、ドキュメントをグループ化してみます。 _search
エンドポイントで Aggregation を使えます。
Bucket ごとにまとめただけでは、デフォルトでドキュメント数のみが返されます。
GET item/_search { "size": 0, "aggs": { <-- Aggregation を使う "category_bucket": { "terms": { <-- Keyword 型のフィールドに対し、指定する値に一致するグループにドキュメントを分類する "field": "category" <-- category でドキュメントをグループ化する } } } } // レスポンス { "took": 14, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 4, "relation": "eq" }, "max_score": null, "hits": [] }, "aggregations": { "category_bucket": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ <-- category ごとのドキュメント数が返ってくる { "key": "noodle", "doc_count": 2 }, { "key": "meat", "doc_count": 1 }, { "key": "vegetable", "doc_count": 1 } ] } } }
値の幅でBucketを使うこともできます。
GET item/_search { "size": 0, "aggs": { "price_bucket": { "range": { "field": "price", "ranges": [ { "to": 1000 }, { "from": 1000, "to": 2000 }, { "from": 2000, "to": 3000 } ] } } } } // レスポンス { "took": 1, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 4, "relation": "eq" }, "max_score": null, "hits": [] }, "aggregations": { "price_bucket": { "buckets": [ { "key": "*-1000.0", <-- グループ化された値の幅を示す "to": 1000, "doc_count": 0 }, { "key": "1000.0-2000.0", "from": 1000, "to": 2000, "doc_count": 2 }, { "key": "2000.0-3000.0", "from": 2000, "to": 3000, "doc_count": 2 } ] } } }
最後にMetricsを合わせて使ってみます。
Aggregationは入れ子に指定できるようで、以下のようにaggsの中にaggsを使います。
つぎのAggregationはcategoryごとのpriceの平均値を取得します。
GET item/_search { "size": 0, "aggs": { "category_bucket": { "terms": { "field": "category" }, "aggs": { "price_avg": { "avg": { "field": "price" } } } } } } // レスポンス { "took": 1, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 4, "relation": "eq" }, "max_score": null, "hits": [] }, "aggregations": { "category_bucket": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "noodle", "doc_count": 2, "price_avg": { "value": 1250 <-- categoryごとのpriceの平均値 } }, { "key": "meat", "doc_count": 1, "price_avg": { "value": 2500 } }, { "key": "vegetable", "doc_count": 1, "price_avg": { "value": 2000 } } ] } } }