Data型データに対して、特定時間帯を検索する方法について

夜間(22:00-06:00)や昼間(08:00-17:00)などのように、時間帯を絞った毎日の検索をしたうえで各種グラフを作成を考えております。
毎日の全時間帯を集約したグラフはよく話題に上がりますが、毎日の特定時間帯だけをグラフにしたいです。

Cut&Try繰り返しても、うまくいかず。
皆様のお知恵を貸してください。

登録するIndexは一種類。logstash-yyyy-MM-dd などのように、時間ごとのindex作成はしない構成。

下記のmappingを登録。
"mappings" : {
"my_index" : {
"properties" : {
"Time" : {
"type" : "date",
"format" : "yyyy-MM-dd HH:mm:ss"
},
"count" : {
"type" : "integer"
}

Kibana上部の検索窓で、date型のTimeに対して、下記のようなqueryをするイメージで試しました。
Time:["* 22:00:00" TO "* 06:00:00"]

しかし、date型では、正規表現は受け付けてもらえないようなエラーメッセージとなっています。
(正規表現にフォーカス当てるため、右記のquery入力で確認。Time:/????/-02-28" 20:13:38")
Discover: Can only use regexp queries on keyword and text fields - not on [Time] which is of type [date]

date型データそのまま利用するのはあきらめて、下記試しましたがうまくいかない状況です。
・fileldsを用いて、string型の別データとして用意
→検索してもヒットせず。Management画面で確かにsearchable/aggregatableともにONになっていない
→Discover: "field" is a required parameter と表示されて、データが認識されない場合もあり
・"is_searchable": "true","is_aggregatable": "true"を追加。
→mapping登録時に、Elasticsearch Ver5.x第では非サポートのエラー。
・copy_toを使って、string型の別データとして用意
→検索してもヒットせず。Management画面で確かにsearchable/aggregatableともにONになっていない

環境
Kibana/Elasticsearch:5.3.0

ちなみに、logstash-yyyy-MM-dd-HH:mm:ss のように、グラフにしたい特定時間帯だけのindexを別に作成すれば、
できそうな気がしますが、できれば、今のindex一個構成のままで何とかできないかなと思っている次第です。

時間が入っているdatetimeを仮に@timestampとしますと、
@timestampから、時間(hour)と分(minute)の部分だけをDateから抜き出して、hourとminuteだけとなる、
HHmmとなるような数値型のフィールドを設けてはどうでしょうか。

例えば、6時15分のデータであれば615、23時45分とすれば2345というように数値で持てば、

22時から6時 は [2200 TO 2359] or [0: TO 600] と表すことができますし、
8時から17時 は[800 TO 1700] と表せそうです。

試しにIngestNodeを用いて、datetimeの@timestampから上記の時間と分部分の数値フィールド(例としてhourtime)とした場合

PUT _ingest/pipeline/discusstest
{
  "description": "discuss test",
  "processors": [
    {
      "script": {
        "lang": "painless",
        "inline": """def df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'+09:00'"); def calendar = Calendar.getInstance(); calendar.setTime(df.parse(ctx['@timestamp'])); ctx.timehour = calendar.get(Calendar.HOUR_OF_DAY)* 100  + calendar.get(Calendar.MINUTE);"""
      }
    }
  ]
}

↑ フォーマットは適当です。手元にあったインデックスに入っていたもので書いてます。

そして、このPipelineを使ってフィールドにデータを格納
保有していた他のindexからreindexで転用しました。

POST _reindex
{
  "source": {
    "index": "入力元のindex(@timestampがあるもの)"
  },
  "dest": {
    "index": "test",
    "pipeline": "discusstest"
  }
}

これで、時間帯をクエリに書くことができ対象が絞れるように思いますがどうでしょう。
es/kibana 5.3.0で確認しました。

1 Like

ご回答ありがとうございます。
こちらの環境ではうまく動作しませんでしたが、HHMMSSの部分だけ整数値として別フィールドに登録するというアイディアはすごく参考になりました。
実際には、date型もこれまで通り利用したいため、ご提案のindex別々に登録せずに、elasticに登録する前段のデータ作成ツールのところで、HHMMSSも出力するような対応をとることにしました。

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.