Kibanaでの描画時に他のindexの内容を利用して集計する方法

初心者のため、質問内容がおかしかったら申し訳ありません。

あるindexの内容を集計してグラフを描画したいのですが、
目標に対する割合を合わせてDataTableなどで描画したいと考えています。

indexA:生ログ
indexB:indexAに含まれる項目ごとの目標値

indexA
category | cost 
A1| 100
A2| 200
A1| 250
A3| 150 

indexB
category | cost 
A1|1000
A2|2000
A3|3000

といった内容の場合、
indexAの内容を集計・描画する際にindexBの内容を分母として
進捗の割合を算出して描画したいのですが、
可能でしょうか。

描画したい内容

category| total | rate
A1 | 350 | 35%
A2 | 200 | 10%
A3 | 150 | 5%

VisualizeやCanvasの中で実装可能なものか
ご教示頂けますと嬉しいです。

@sck_345 さん、

データの JOIN が必要なケースですね。残念ながら簡単に実現する方法はありません。考えられるアプローチは二つあると思います。

一つは Enrich プロセッサを使って、生ログのインジェスト時に、indexBの cost を生ログに埋め込む方法です。これは indexB の目標値が頻繁に変わらないケースなら現実的かと思います。

もう一つはクエリ DSL で複雑なアグリゲーションを実行した結果を Vega で描画する方法です。Vega だと自由にクエリ DSL を記述できるので便利です。こちらの方法について、以下に部分的なサンプルを記載しておきます。

サンプルデータセット

indexAに相当するデータです。 constant_keyword を使って生ログというラベルを付けています。

PUT forum_249929_a
{"mappings":{"properties":{"type":{"type":"constant_keyword","value":"raw_log"}}}}

POST forum_249929_a/_bulk
{"index":{}}
{"category":"A1","cost":100}
{"index":{}}
{"category":"A2","cost":200}
{"index":{}}
{"category":"A1","cost":250}
{"index":{}}
{"category":"A3","cost":150}

indexB に相当するデータです、こちらは goal というラベルをつけています。

PUT forum_249929_b
{"mappings":{"properties":{"type":{"type":"constant_keyword","value":"goal"}}}}

POST forum_249929_b/_bulk
{"index":{}}
{"category":"A1","cost":1000}
{"index":{}}
{"category":"A2","cost":2000}
{"index":{}}
{"category":"A3","cost":3000}

この二つのインデックスを同時にアグリゲーションで処理します。 filter アグリゲーションでそれぞれのバケットを分けつつ、 bucket_script で目標値への到達率を計算しています。

GET forum_249929_*/_search
{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": {
        "field": "category.keyword",
        "size": 10
      },
      "aggs": {
        "actual": {
          "filter": {
            "term": {
              "type": "raw_log"
            }
          },
          "aggs": {
            "value": {
              "sum": {
                "field": "cost"
              }
            }
          }
        },
        "goal": {
          "filter": {
            "term": {
              "type": "goal"
            }
          },
          "aggs": {
            "value": {
              "max": {
                "field": "cost"
              }
            }
          }
        },
        "rate": {
          "bucket_script": {
            "buckets_path": {
              "actual": "actual>value",
              "goal": "goal>value"
            },
            "script": "(params.actual / params.goal) * 100"
          }
        }
      }
    }
  }
}

上記のクエリを実行すると、次の結果が得られます (長いので一部抜粋)。結果の rate.value を Vega で描画してやればやりたいことはできそうです。Vega の使い方はこちらのチュートリアルを参考にしてください。

"categories" : {
      "buckets" : [
        {
          "key" : "A1",
          "doc_count" : 3,
          "actual" : {
            "doc_count" : 2,
            "value" : {
              "value" : 350.0
            }
          },
          "goal" : {
            "doc_count" : 1,
            "value" : {
              "value" : 1000.0
            }
          },
          "rate" : {
            "value" : 35.0
          }
        },
        {
          "key" : "A2",
          "doc_count" : 2,
          "actual" : {
            "doc_count" : 1,
            "value" : {
              "value" : 200.0
            }
          },
          "goal" : {
            "doc_count" : 1,
            "value" : {
              "value" : 2000.0
            }
          },
          "rate" : {
            "value" : 10.0
          }
        },
        {
          "key" : "A3",
          "doc_count" : 2,
          "actual" : {
            "doc_count" : 1,
            "value" : {
              "value" : 150.0
            }
          },
          "goal" : {
            "doc_count" : 1,
            "value" : {
              "value" : 3000.0
            }
          },
          "rate" : {
            "value" : 5.0
          }
        }
      ]
    }

ご参考になれば幸いです。