Elasticsearch时间类型实战

目录

前言

一、核心基础:ES时间类型底层原理

[1.1 ES时间类型唯一标准:date](#1.1 ES时间类型唯一标准:date)

[1.2 ES date 底层核心特性](#1.2 ES date 底层核心特性)

[1.3 ES官方两种标准时间格式](#1.3 ES官方两种标准时间格式)

[1.3.1 通用兼容格式(生产首选)](#1.3.1 通用兼容格式(生产首选))

[1.3.2 自定义本地时间格式](#1.3.2 自定义本地时间格式)

二、ES时间字段Mapping实战配置(两套可用方案)

[2.1 方案一:自定义本地时间格式(适配MySQL原样同步)](#2.1 方案一:自定义本地时间格式(适配MySQL原样同步))

[2.2 方案二:UTC标准格式](#2.2 方案二:UTC标准格式)

[三、Java实体类适配+Java API Client查询实战](#三、Java实体类适配+Java API Client查询实战)

[3.1 适配自定义格式(yyyy-MM-dd HH:mm:ss)](#3.1 适配自定义格式(yyyy-MM-dd HH:mm:ss))

[3.1.1 实体类配置](#3.1.1 实体类配置)

[3.2 适配UTC标准格式(strict_date_optional_time)](#3.2 适配UTC标准格式(strict_date_optional_time))

[3.2.1 实体类配置](#3.2.1 实体类配置)

四、全网高频报错:LocalDateTime反序列化失败(根治方案)

[4.2 报错根因](#4.2 报错根因)

[4.3 分步解决方案](#4.3 分步解决方案)

第一步:引入依赖

第二步:手动配置ES客户端(核心根治)


前言

在实际开发中,Elasticsearch(下文简称ES)时间类型的使用是高频易错点,绝大多数开发者都会遇到时区错乱、序列化报错、MySQL与ES数据同步不一致、Java API查询反序列化失败等问题。

本文结合真实开发场景,从零梳理ES时间类型底层原理、Mapping配置规范、Java实体适配、MySQL数据同步方案、全网最常见报错及根治方案解决所有ES时间相关疑难问题。

一、核心基础:ES时间类型底层原理

1.1 ES时间类型唯一标准:date

ES 中所有时间字段,必须使用 date 类型,绝对禁止使用 keyword、text、long 存储业务时间:

  • 禁止字符串存储:无法范围查询、时间聚合、排序失效

  • 禁止纯long时间戳存储:可读性极差,排查问题困难,可视化查询不友好

1.2 ES date 底层核心特性

无论你传入什么格式的时间,ES底层统一存储【UTC毫秒时间戳】,所有格式化展示、时区适配都是上层封装,底层无字符串概念。

这是ES和MySQL时间设计的本质区别,也是所有时区BUG的根源:

  • MySQL datetime:纯本地时间字符串,无时区属性,绑定服务器时区

  • ES date:绝对时间戳,默认强制识别为UTC 0时区

1.3 ES官方两种标准时间格式

1.3.1 通用兼容格式(生产首选)

适配时间字符串+毫秒时间戳,兼容性最强,官方默认配置:

"format": "strict_date_optional_time||epoch_millis"

支持入库格式:

  • 标准UTC时间:2025-05-08T10:20:30.123Z

  • 秒级UTC时间:2025-05-08T10:20:30Z

  • 毫秒时间戳:1746728430123

1.3.2 自定义本地时间格式

适配MySQL默认时间格式,无时区,仅限全环境东八区场景:

"format": "yyyy-MM-dd HH:mm:ss"

支持入库格式:2025-05-08 10:20:30

自定义的时间格式可以随意自定义,只是搭建可以看一下底层原理,就理解了为什么不太推荐使用。

二、ES时间字段Mapping实战配置(两套可用方案)

本文提供实战偷懒方案(中小企业)标准化规范方案(大厂生产),按需选用。

2.1 方案一:自定义本地时间格式(适配MySQL原样同步)

适用场景:国内单体项目、全服务器东八区、无海外业务、无需跨时区统计

优点:MySQL数据无需转换,同步代码极简,开发效率高

缺点:不支持跨时区,扩展性差

复制代码
PUT /order_index_001
{
  "settings": {
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "order_id": { "type": "keyword" },
      "price": { "type": "scaled_float", "scaling_factor": 100 },
      "pay_num": { "type": "integer" },
      "order_time": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" },
      "category": { "type": "keyword" }
    }
  }
}

2.2 方案二:UTC标准格式

适用场景:微服务、分布式项目、上云项目、有海外业务、大数据统计

优点:无时区BUG、全球统一、支持所有时间查询/聚合、扩展性拉满

复制代码
PUT /order_index_001
{
  "settings": {
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "order_id": { "type": "keyword" },
      "price": { "type": "scaled_float", "scaling_factor": 100 },
      "pay_num": { "type": "integer" },
      "order_time": { "type": "date", "format": "strict_date_optional_time||epoch_millis" },
      "category": { "type": "keyword" }
    }
  }
}

三、Java实体类适配+Java API Client查询实战

下面的例子中展示了使用不同的时间格式,Java实体类的类型。

3.1 适配自定义格式(yyyy-MM-dd HH:mm:ss)

3.1.1 实体类配置

对应Mapping无时区格式,使用 LocalDateTime,必须加格式化注解

java 复制代码
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;

@Data
public class OrderIndex {
    private String order_id;
    private Double price;
    private Integer pay_num;
    private String category;

    // 格式必须与ES Mapping完全一致
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime order_time;
}

3.2 适配UTC标准格式(strict_date_optional_time)

3.2.1 实体类配置

对应ES UTC时间,使用 Instant(绝对UTC时间,无时区BUG)

java 复制代码
import lombok.Data;
import java.time.Instant;

@Data
public class OrderIndex {
    private String order_id;
    private Double price;
    private Integer pay_num;
    private String category;

    // 标准UTC时间,无需格式化注解
    private Instant order_time;
}

四、全网高频报错:LocalDateTime反序列化失败(根治方案)

复制代码

co.elastic.clients.json.JsonpMappingException: Error deserializing co.elastic.clients.elasticsearch.core.search.Hit: jakarta.json.JsonException: Jackson exception Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling

4.2 报错根因

很多同学只加依赖仍报错,核心原因:

  • Spring默认ObjectMapper支持Java8时间类型,但ES Java Client拥有独立的ObjectMapper

  • ES客户端默认未注册Java8时间模块,无法解析LocalDateTime/LocalDate

4.3 分步解决方案

第一步:引入依赖

XML 复制代码
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

第二步:手动配置ES客户端(核心根治)

手动为ES独立的ObjectMapper注册时间模块,彻底解决解析失败问题

如果大家使用的是安全模式下的es连接,可以查看博主的文章:

Java 连接 Elasticsearch 8.x 安全模式实战:证书校验与 ApiKey 认证全解析_elasticsearch 不加spring 连接es服务 ssl校验-CSDN博客

上述文中中的连接时没有配置时间的,大家在结合这个文章中的配置,进行一下时间模块的注册就可以了。

java 复制代码
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.elasticsearch.client.RestClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class EsClientConfig {

    @Bean
    public ElasticsearchClient elasticsearchClient(RestClient restClient) {
        // 注册Java8时间模块,支持LocalDateTime/Instant解析
        ObjectMapper objectMapper = new ObjectMapper()
                .registerModule(new JavaTimeModule());
        JacksonJsonpMapper mapper = new JacksonJsonpMapper(objectMapper);
        ElasticsearchTransport transport = new RestClientTransport(restClient, mapper);
        return new ElasticsearchClient(transport);
    }
}
相关推荐
Elastic 中国社区官方博客1 小时前
Elastic 9.4:Workflows 正式发布、Agent Builder 更新,以及 Prometheus / PromQL 支持
运维·数据库·人工智能·elasticsearch·搜索引擎·信息可视化·prometheus
Gerardisite2 小时前
企微批量群发消息指南:用 QiWe 省掉人工操作
java·python·机器人·企业微信
Dxy12393102163 小时前
Python如何处理树状分类数据
大数据·python·分类
青山师3 小时前
动态代理深度解析:JDK与CGLIB底层实现与实战
java·设计模式·面试·动态代理·java面试·cglib
放学后的泡泡3 小时前
提供一个工作流的表设计
java·设计规范
凡人AI录4 小时前
小红书商业变现 100 个关键词:从流量逻辑到长期复利
大数据
生活真难4 小时前
SpringCloud - 任务调度 - xxl-job-java
java·spring boot·spring cloud
zhongerzixunshi4 小时前
筑牢国家安全防线,赋能企业合规发展
大数据·人工智能·安全
小飞象—木兮4 小时前
2026数据资产入表解决方案(52页 PPT)
大数据·人工智能