from 30

30歳からwebエンジニアになったけど、思ったよりも苦しいので、その苦闘の記録をば

elasticsearchのdateでepoch_secondを使用する

経緯

普段はpythonを使用している。 日付関連は基本的にtimestampを使用している。 pythonのdatetimeモジュールにおけるtimestampは秒単位(10桁)になっている。

一方でelasticsearchのtype: dateはmillisecになっている。 elasticsearchにindexするときに、日付データを1000倍にする。取り出す時に1000分の1にするという方法もあるけど間違えそう。

また、検索についてはisoformatを使って柔軟に処理したいというニーズもある。

ということで、 - データ投入ではtimestampを使用 - クエリではtimestampもisoformatも柔軟に対応できる そんな方法はないと悩んだ次第である。

解決策

formatを使用して解決した。 以下はmappingsの抜粋。

"created_at": {
  "type": "date",
  "format": "epoch_second||date_optional_time"
}

formatは||を指定することで複数指定可能である。 今回は - epoch_second(millisecondsではなくて) - date_optional_time を登録してみた。

以下は投入データとクエリの例 とりあえずやりたいことはできている。

PUT /test/_doc/1
{
  "created_at": 1577876400 //10桁timestampで投入可
}

GET /test/_search
{
  "query": {
    "range": {
      "created_at": {
        "from": "2020-01-01T20:00:00" //フルisoformat
      }
    }
  }
}
GET /test/_search
{
  "query": {
    "range": {
      "created_at": {
        "from": "2020-01-01T20:00:00.000" //millisecまで込みのフルisoformat
      }
    }
  }
}
GET /test/_search
{
  "query": {
    "range": {
      "created_at": {
        "from": "2020-01-01T20" // 欠落しててもOK
      }
    }
  }
}
GET /test/_search
{
  "query": {
    "range": {
      "created_at": {
        "from": 1599999999, // 10桁timestamp
        "to": 1600000001
      }
    }
  }
}

最後に

日付関連はめんどくさい。