【Datatable】Top hits Aggregationに関して

お世話になります。
以前質問させて頂いた、DatatableのTop hits Aggregationに関して再度質問させて頂きます。

▼実現したいこと
下記indexデータにおいて
同一のnameの中でtimeが最も過去日付のデータのみ、Datatableに表示

▼indexデータ
index patternの時間フィルター:timeを設定

name id time
AAA 1 Jun 1, 2020 @ 10:00:00.000 …①
AAA 1 Feb 1, 2020 @ 10:00:00.000 …②

▼Datatableの設定値



▼Datatableの取得結果
1.time filterが1月(Jan 1, 2020 @ 00:00:00.000~Jan 31, 2020 @ 23:59:59.999)の場合

name id time
AAA 1 Jun 1, 2020 @ 10:00:00.000 …①

2.time filterが2月(Feb 1, 2020 @ 00:00:00.000~Feb 29, 2020 @ 23:59:59.999)の場合

name id time
AAA 1 Feb 1, 2020 @ 10:00:00.000 …②

◆ご質問
indexの全体期間を対象とすると①が最も過去日付のため、2.の場合は②を表示させないようにしたいです。

dataTableのtime filter(timeが時間軸)が2月データを対象としているため、②が表示される(①は対象外)のですが、
top hit aggregationの取得期間は全体期間かつdataTableのtime filterは対象月を指定する方法はありますでしょうか?

お手数ですが、回答頂けますと幸いです。
以上、宜しくお願い致します。

@harue さん、
なかなか難しいですね、Data Tableでの実現方法は思いつきませんでした。できないと思います。ちょっとデータテーブルとは表示結果が異なりますが、Vegaならやりたいことはできそうです。ご参考になれば幸いです。

まず、こちらは 次のデータセットで試しました:

POST forum_237414/_bulk
{"index":{"_id":"1"}}
{"name":"A","time":"2020-01-01T10:00:00+09:00"}
{"index":{"_id":"2"}}
{"name":"A","time":"2020-01-01T20:00:00+09:00"}
{"index":{"_id":"3"}}
{"name":"A","time":"2020-02-01T10:00:00+09:00"}
{"index":{"_id":"4"}}
{"name":"A","time":"2020-02-01T20:00:00+09:00"}
{"index":{"_id":"5"}}
{"name":"B","time":"2020-02-10T10:00:00+09:00"}
{"index":{"_id":"6"}}
{"name":"B","time":"2020-02-20T20:00:00+09:00"}

上記データセットを使った際のVega描画結果が以下になります。
まず、タイムピッカーで全データセットを範囲内に収めた場合です。

ここではA, B共に、それぞれの一番古い日付が表示できています。

次に、タイムピッカーで、Aの最も古い日付は範囲外だが、それ以外の日付は範囲内に存在するケースです。これが本質問で非表示にされたいケースだと思います。Bについては最も古い日付が範囲内に収まっているので、表示されています。

今回の例では意図的にAのレコードは描画したまま、日付のみnot foundとしました。レコードを描画しないことも可能です。

データテーブルと見え方は違えど、やりたいことはこれでできるかな、と思います。あとは見せ方を調整してもう少し表っぽくみせたり、場合によってはX軸の時系列をうまく使って、表形式よりも分かりやすい可視化が可能かもしれません。

この例では以下のVega Liteスペックを書いてみました。ポイントは:

  • queryは記述せず、フィルタリングしないで全データセットを使ってoldestアグリゲーションを実行している
  • 最も古いタイムスタンプを探すのは terms を使う。ここで top_hits を使ってしまうと、それ以上何もできないので
  • その後、Kibana Vegaのタイムピッカーマッピング {"%timefilter%": "min"} とmaxを使って最終データを絞り込みます。
  • 最後に、top_hitsで該当ドキュメントを取得
  • 対象外となった場合、calculate を使って not found としていますが、ここで filter を使えばレコード自体を非表示にすることも可能と思います
{
  "$schema": "https://vega.github.io/schema/vega-lite/v2.json",
  "title": "全日付範囲でaggしつつ結果はTimeFilterで絞る",
  "data": {
    "url": {
      "index": "forum_237414",
      "body": {
        "size": 0,
        "aggs": {
          "by_name": {
            "terms": {"field": "name.keyword", "size": 10},
            "aggs": {
              "oldest": {
                "terms": {"size": 1, "field": "time", "order": {"_key": "asc"}},
                "aggs": {
                  "timefilter": {
                    "filter": {
                      "range": {
                        "time": {
                          "gte": {"%timefilter%": "min"},
                          "lt": {"%timefilter%": "max"}
                        }
                      }
                    },
                    "aggs": {"timefiltered": {"top_hits": {"size": 1}}}
                  }
                }
              }
            }
          }
        }
      }
    },
    "format": {"property": "aggregations.by_name.buckets"}
  },
  "transform": [
    {
      "calculate": "datum.oldest.buckets[0].timefilter.timefiltered.hits.total.value > 0 ? datum.oldest.buckets[0].timefilter.timefiltered.hits.hits[0] : null",
      "as": "timefiltered"
    },
    {
      "calculate": "datum.timefiltered ? datum.timefiltered._source.time : 'not found'",
      "as": "time"
    }
  ],
  "encoding": {
    "y": {"field": "key", "type": "ordinal", "axis": {"title": "name"}}
  },
  "layer": [
    {
      "mark": {"type": "point", "filled": true, "size": 100},
      "encoding": {
        "x": {
          "field": "oldest.buckets[0].timefilter.timefiltered.hits.hits[0]._source.time",
          "type": "temporal",
          "axis": {"title": false, "grid": false}
        }
      }
    },
    {"mark": "text", "encoding": {"text": {"field": "time", "type": "nominal"}}}
  ]
}