You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ElasticSearch查询中将日期转为yyyyMMdd数字格式并返回至_source?

没问题,我来教你怎么把Elasticsearch里的ISO格式日期转成yyyyMMdd的数字格式返回~

核心思路是用Painless脚本完成日期拆分、补零拼接、转数字这几个步骤,下面给你几种常用的实现方式:

方式一:用脚本字段(Script Fields)返回目标格式

这种方式会在查询响应里新增一个独立字段,和原_source并列返回,不修改原始数据:

{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "updated_yyyyMMdd": {
      "script": {
        "lang": "painless",
        "source": """
          // 获取日期对象
          ZonedDateTime dt = doc['updated'].value;
          // 提取年、月、日
          int year = dt.getYear();
          int month = dt.getMonthValue(); // 推荐用getMonthValue()替代旧的getMonthOfYear()
          int day = dt.getDayOfMonth();
          // 格式化拼接成yyyyMMdd字符串,再转成数字
          return Long.parseLong(String.format("%04d%02d%02d", year, month, day));
        """
      }
    }
  },
  "_source": ["updated"] // 可选:保留原updated字段,按需调整
}

执行后,响应里会多出fields.updated_yyyyMMdd字段,值就是你要的数字(比如20200104)。

方式二:用Runtime Field整合到_source中

如果希望目标字段直接出现在_source里,可以用查询时定义的Runtime Field:

{
  "query": {
    "match_all": {}
  },
  "runtime_mappings": {
    "updated_yyyyMMdd": {
      "type": "long",
      "script": """
        ZonedDateTime dt = doc['updated'].value;
        int year = dt.getYear();
        int month = dt.getMonthValue();
        int day = dt.getDayOfMonth();
        emit(Long.parseLong(String.format("%04d%02d%02d", year, month, day)));
      """
    }
  },
  "_source": ["updated", "updated_yyyyMMdd"] // 指定返回原字段和新增的runtime字段
}

这样返回的_source里就会同时包含原updated和格式化后的updated_yyyyMMdd数字字段。

方式三:修改你的排序脚本

如果需要在排序时使用这个数字,同时也要返回它,可以把排序脚本和脚本字段结合:

{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "_script": {
        "type": "number",
        "script": {
          "lang": "painless",
          "source": """
            ZonedDateTime dt = doc['updated'].value;
            int year = dt.getYear();
            int month = dt.getMonthValue();
            int day = dt.getDayOfMonth();
            return Long.parseLong(String.format("%04d%02d%02d", year, month, day));
          """
        },
        "order": "desc"
      }
    }
  ],
  "script_fields": {
    "updated_yyyyMMdd": {
      "script": {
        "lang": "painless",
        "source": """
          ZonedDateTime dt = doc['updated'].value;
          int year = dt.getYear();
          int month = dt.getMonthValue();
          int day = dt.getDayOfMonth();
          return Long.parseLong(String.format("%04d%02d%02d", year, month, day));
        """
      }
    }
  },
  "_source": ["updated"]
}

关键注意点

  • 补零处理:用%02d格式化月份和日期,确保1月变成01、4日变成04,避免出现202014这种错误格式。
  • 数字类型选择:用Long.parseLong转成Long类型,比Int更稳妥(虽然8位数字在Int范围内,但Long兼容性更好)。
  • 日期API:Elasticsearch的Painless中,doc['updated'].value是ZonedDateTime类型,推荐用getMonthValue()获取月份(旧的getMonthOfYear()已逐步废弃)。

内容的提问来源于stack exchange,提问作者user379151

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:17:55