RedashのデータソースとしてElasticsearchが使えるようなので、試してみた所、色々と問題がある事が分かった。
環境
Redash(v7.0.0)
Elasticsearch(v7.3.2)
問題
Elasticsearchからのクエリ結果を正しく(期待する)表形式にできない。
RedashからQueryを実行すると、下記のようにQueryRunnerを介してクエリの発行及び、結果表示が行われている。
画面からQuery実行 → QueryRunner → Elasticsearch → QueryRunner → 画面に結果を表形式で表示
Elasticsearchからのクエリ結果は期待通りになっている事を確認できたので、今回の問題は、Elasticsearchからのクエリ結果をQueryRunnerで表形式にパースできていないとこにある事が分かった。
複数Aggregationのクエリを実行した際の結果
下記のようなAggregationを入れ子にしたクエリを実行。
{
"index": "インデックス名",
"size": 1000,
"aggs": {
"1st": {
"terms": {
"field": "LogDate"
},
"aggs": {
"2nd": {
"terms": {
"field": "SectionName"
}
}
}
}
}
}
イメージ的には、日付、部署で集計するので、下記のような結果を期待。
LogDate | SectionName | 数 |
---|---|---|
2019年10月29日 | システム部 | 10 |
2019年10月29日 | 人事部 | 20 |
2019年10月29日 | 総務部 | 30 |
2019年10月30日 | システム部 | 100 |
2019年10月30日 | 人事部 | 200 |
2019年10月30日 | 総務部 | 300 |
しかし、RedashでTableの結果として表示されるのは、下記のようになる。
→もはや、何で集計されていて、何の数か分からない。
2nd | doc_count |
---|---|
(SectionNameの何かしらの値) | 110 |
(SectionNameの何かしらの値) | 220 |
(SectionNameの何かしらの値) | 330 |
JSONの構造が複雑になるケース
例えば、Sum Bucket Aggregationを使用した場合、Elasticsearchからのクエリ結果は下記のように、バケットのルートと同じ階層に別バケットが存在する。
{
・
・
・
"aggregations": {
"バケット名": {
"buckets": [
{
バケット結果
}
]
},
"SUM BUCKET名": {
"value": 1000.0
}
}
}
結果は、"バケット名"の方だけ表形式で表示される
※"バケット名"の方だけ表形式で表示されるが、Aggregationが入れ子の場合には、前述の問題が発生
※"SUM BUCKET名"の方は捨てられる
対応方法
これらの問題を解決するには、
・Redashの既存ソースを修正するか、拡張プログラムを追加して、プログラム対応を行う
拡張プログラムの対応は、「RedashのQueryRunnerを拡張する」を参考にして頂ければ
・ISSUEを起票してアップデート待ち(もしくは、自分で動く)
まとめ
多分、Elasticsearchをデータソースとする場合、Kibanaを選択する事が多いのか、発生した問題の挙動(クエリパターンとして、絶対あたるであろう)からしてほとんど使われてないのかな。
「データソースをElasticsearchにするなら、Redashは使わない」
「Redashを使うなら、データソースをElasticsearchにしない、もしする場合にはシンプルなクエリのみ」
のようにして、実現させた方が効率的だと感じました。
余談
データソースにKibanaにしたら結果が変わるかなと思いやってみましたが、Kibana用のクエリの記述で処理されるだけなので、同様の結果になりました。
データソースがKibanaではなく、あくまでクエリがKibana用で記述できるだけの挙動でした。
※こうではないので、注意が必要
Kibanaを通した結果を得られるわけではない
画面からQuery実行 → QueryRunner → Kibana(Elasticsearch) → QueryRunner → 画面に結果を表形式で表示