Date型をepochミリ秒で取得することはできますか


(tsukahara) #1

現在 Elasticsearch6.2.2を使用しております。
データの登録時にdate型を"yyyy/mm/dd"などで登録したデータに対して、
検索結果のdate型の値を epochミリ秒で取得する方法ありますでしょうか。

1文書のみであればaggsを使うとepochミリ秒が取れることがわかったのですが、
検索結果(_sourceの箇所)として取る方法があれば教えていただきたく
質問させていただきました。

データ登録例

POST aaa/type/1?refresh=true
{
  "cdate": "2019/02/08"
}

検索例

GET aaa/_search
{
  "aggs": {
    "cdate": {
      "max": {
        "field": "cdate"
      }
    }
  }
}

検索結果

        "_source": {
          "cdate": "2019/02/08"
        }
      }
    ]
  },
  "aggregations": {
    "cdate": {
      "value": 1549584000000,
      "value_as_string": "2019/02/08 00:00:00"
    }
  }

(tsgkdt) #2

script fieldを利用するのはどうでしょう?

データ登録

PUT forum0208/_doc/1
{
  "title": "epochでほしい",
  "date": "2019-02-08T14:37:15+0900"
}

クエリ

GET forum0208/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "converted_date1": {
      "script": {
        "lang": "painless",
        "source": "doc['date'].value.toInstant().toEpochMilli()"
      }
    }
  }
}

結果

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "forum0208",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "fields" : {
          "converted_date1" : [
            1549604235000
          ]
        }
      }
    ]
  }
}


(tsukahara) #3

早速の回答ありがとうございます。
いただいた例で試してみたのですが、こちらの環境ですと以下のエラーとなってしまいました。

    "reason": {
      "type": "script_exception",
      "reason": "runtime error",
      "script_stack": [
        "doc['date'].value.toInstant().toEpochMilli()",
        "                 ^---- HERE"
      ],
      "script": "doc['date'].value.toInstant().toEpochMilli()",
      "lang": "painless",
      "caused_by": {
        "type": "illegal_argument_exception",
        "reason": "Unable to find dynamic method [toInstant] with [0] arguments for class [org.joda.time.MutableDateTime]."
      }
    }

以下とすることでepochミリ秒が取得できましたので
scriptを利用したいと思います。

    "source": "doc['date'].value.toInstant().toEpochMilli()"
    ↓
    "source": "doc['cdate'].value.getMillis()"

ありがとうございます。


(tsgkdt) #4

バージョンが6.2.2であるところを、うっかり見落としておりました。

最新の6.6.0ですと、getMillisはdeprecatedとなっておりますので、今後のバージョンアップの際はご留意いただくと良いと思いますー

Query

GET forum0208/_search
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "converted_date1": {
      "script": {
        "lang": "painless",
        "source": "doc['date'].value.getMillis()"
      }
    }
  }
}

とすると、deprecatedログが出る。

#! Deprecation: Use of the joda time method [getMillis()] is deprecated. Use [toInstant().toEpochMilli()] instead.

ご参考まで。


(tsukahara) #5

情報ありがとうございます。
新しいバージョンでは違う呼び出し方になっているのですね。
機会を見てバージョンアップ(7以降かな)したいと思います。