Elasticsearch7にしたらtoo_many_buckets_exceptionになってしまった
結論
一回でまとめて取得していたものを数回に分けて取得するようにした。
対象のインデックス
GET logs/_mapping
{ "logs" : { "mappings" : { "properties" : { "action" : { "type" : "text" }, "user_id" : { "type" : "integer" }, "company_id" : { "type" : "integer" }, "request" : { "type" : "nested", "properties" : { "id" : { "type" : "integer" }, "type" : { "type" : "text", "fielddata" : true } } }, "timestamp" : { "type" : "date" } } } } }
too_many_buckets_exceptionとは
Elasticsearchの用語に合わせて説明すると 指定した集約(aggregation)方法で分類(Bucket)された数が 1万を超えたために出たエラーである
SQLに例えて説明すると GROUP BY で出力されたレコードの数が 1万を超えた場合である。
実際のElasticsearch で叩いてた内容
まずこんな検索Queryを作ったことを許してほしい
{ "query": { "bool": { "must": [ { "match": { "company_id": 1 } }, { "range": { "timestamp": { "gte": "now-1y", "lt": "now" } } } ] } }, "aggs":{ "by_user_id":{ "terms":{ "field":"user_id", "size":1000000, "missing":0 }, "aggs":{ "by_month":{ "date_histogram":{ "field":"timestamp", "interval":"month", "format":"yyyyMM" }, "aggs":{ "by_request":{ "nested":{ "path":"request" }, "aggs":{ "by_request_type":{ "terms":{ "field":"request.type" }, "aggs":{ "by_request_id":{ "terms":{ "field":"request.id" } } } } } } } } } } } }
SQLで表現すると
SELECT user_id, DATE_FORMAT(timestamp,'%Y-%m') AS month, request_id, request_type FROM logs WHERE company_id = 1 AND timestamp BETWEEN DATE_SUB(NOW(),INTERVAL 1 YEAR) AND NOW() GROUP BY user_id, DATE_FORMAT(timestamp,'%Y-%m'), request_id, request_type
確かに一年間分となるとそうなるよなと思いつつ
このエラーに対する設定は変えられるのだが、
現時点ではElasticsearch 公式では設定ではなくクエリ自体を修正するように勧めている。
公式通り検索範囲を狭めた
一年で1回ではなく 一ヶ月で12回に分けるようにした。
GET logs/_search
{ "query":{ "bool":{ "must":[ { "match":{ "company_id": 1 } }, { "range":{ "timestamp":{ "gte":"2020-01-01T00:00:00.000+09:00", "lte":"2020-01-31T23:59:59.999+09:00" } } } ] } }, "aggs":{ "by_user_id":{ "terms":{ "field":"user_id", "size":1000000, "missing":0 }, "aggs":{ "by_request":{ "nested":{ "path":"request" }, "aggs":{ "by_request_type":{ "terms":{ "field":"request.type" }, "aggs":{ "by_request_id":{ "terms":{ "field":"request.id" } } } } } } } } } }
あとはサーバーサイド側で整えて今回は乗り越えた。
やはり基礎は学んでおかないと。。。
今回はこの本を読んで基本を抑えました。
Kindle unlimitedの対象となっていたので読んでみましたが
例えや図が多く、わかりやすい内容になっているので急いで学ばなくてはいけない人にもおすすめです