RedashのQueryRunnerを拡張する


RedashのElasticsearch用のパーサー(QueryRunner)に問題(RedashでデータソースにElasticsearchを使用した時の問題)を発見したので、問題を解決するためにQueryRunnerを拡張します。
既存ファイルを修正して、対応する事も可能でしたが、それだとバージョンアップの際に手間となるので、今回はQueryRunnerを新規に追加してみました。

環境

Redash(v7.0.0)
Elasticsearch(v7.3.2)
docker

拡張内容

Elasticsearchで複数Aggregationのクエリ結果をRedashの結果として、表形式で正しく表示する。
具体的には、GROUP BY 項目1,項目2のように指定した時と同じような表結果を得られれば、Redashでグラフを作成する事が可能なため。

以下のようなElasticsearchからのクエリ結果を表形式にパースする。(結果構造から一部データを省略)

{
    "aggregations": {
        "1st": {
            "buckets": [
                {
                    "key": "2019年10月29日",
                    "doc_count": 60,
                    "2nd": {
                        "buckets": [
                            {
                                "key": "システム部",
                                "doc_count": 10
                            },
                            {
                                "key": "人事部",
                                "doc_count": 20
                            },
                            {
                                "key": "総務部",
                                "doc_count": 30
                            }
                        ]
                    }
                },
                {
                    "key": "2019年10月30日",
                    "doc_count": 600,
                    "2nd": {
                        "buckets": [
                            {
                                "key": "システム部",
                                "doc_count": 100
                            },
                            {
                                "key": "人事部",
                                "doc_count": 200
                            },
                            {
                                "key": "総務部",
                                "doc_count": 300
                            }
                        ]
                    }
                }
            ]
        }
    }
}

Redashへの追加方法

新規のQueryRunnerを追加する場合には、予め用意されている環境変数"REDASH_ADDITIONAL_QUERY_RUNNERS"で追加が行えます。

Redashで用意されている環境変数の一覧

追加の読み込み設定

docker-compose.ymlに設定の追加を行います。
追加はenvironmentのセクションに追記します。

docker-compose.yml
environment:
  REDASH_ADDITIONAL_QUERY_RUNNERS: "redash.query_runner.elasticsearch_custamize"

追加ファイルの配置

既に既存のファイルが配置されているディレクトリ内に、今回追加するファイルを配置します。

redash/query_runner
 elasticsearch.py
 oracle.py
 pg.py
   ・
   ・
 elasticsearch_custamize.py
   ・

Dockerコンテナの起動(再起動)

開発版で確認する場合、redash直下のdocker-compose.ymlをベースに、docker-composeを行います。
リリース版で確認する場合、予めファイルを配置したRedashのImageを作成しておくなりして、redash/setup直下のdocker-compose.ymlをベースに、docker-composeを行います。
※起動時に追加指定した箇所に対象のファイルがないとエラーになります。

redash
  /setup
    docker-compose.yml ← リリース版用
  Dockerfile
  docker-compose.yml  ← 開発用

追加したQueryRunnerの使用

New Data Sourceから追加したData Sourceを選択する。

正しく読み込めていると、Data Sourceの一覧に表示されます。
※Data Sourceに対する画像が別で管理されているようで、今回は既存のElasticsearchを残したまま別名で作成したので、何も画像が表示されていないようです。

下記のように名前をずらさないと、既存の物が上書きされるので、注意が必要。

elasticsearch_custamize.py
class ElasticsearchCustom(BaseElasticSearch):

    @classmethod
    def name(cls):
        return 'ElasticsearchCustom'

register(ElasticsearchCustom)

Elasticsearchの接続情報を入力してSAVEを行う。
今回追加したelasticsearch_custamize.pyで設定情報を定義する事となりますが、今回は既存のelasticsearch.pyの拡張版の為、接続定義情報は既存のElasticsearchと同じように登録します。

Queryから登録したData Sourceを使用してクエリを作成して、実行

実行するクエリは下記の通り。

{
    "index": "インデックス名",
    "size": 100,
    "aggs": {
        "1st": {
            "terms": {
                "field": "LogDate"
            },
            "aggs": {
                "2nd": {
                    "terms": {
                        "field": "SectionName"
                    }
                }
            }
        }
    }
}

elasticsearch_custamize.pyで処理した結果が、Tableに表示される。

1st 2nd 1st_doc_count 2nd_doc_count
2019年10月29日 システム部 60 10
2019年10月29日 人事部 60 20
2019年10月29日 総務部 60 30
2019年10月30日 システム部 600 100
2019年10月30日 人事部 600 200
2019年10月30日 総務部 600 300

この表結果が得られれば、グラフを作成できる!

もしこれでカバーできない要件が来た時に、色々なクエリ結果のJSONパターンを加味して、プログラムを複雑化させるよりかは、QueryResultの合わせ技で実現するのも手かなと。