Spark写入Elasticsearch时Timestamp字段转为Long类型的问题求助
我来帮你解决这个Timestamp字段被转成Long类型的问题,这是Spark Elasticsearch连接器里很常见的映射配置问题,咱们一步步来搞定它:
问题根源
你虽然设置了es.mapping.date.rich: "True",但这个配置需要配合正确的日期格式才能生效。默认情况下,如果连接器无法识别Timestamp对应的ES日期格式,就会把Timestamp转成毫秒级的Long时间戳存储,这就是你看到的现象。另外还要注意,ES自动创建的索引映射有时候不会正确识别Spark的Timestamp类型,容易 fallback 到Long。
解决方案
1. 先检查现有ES索引的映射
首先确认你的index_esche索引里这三个字段的类型,用ES的REST API查询:
GET index_esche/_mapping
如果返回结果里Createdon、Updatedon、Resolvedon的类型是long,那说明自动创建的映射不对,需要修正。
2. 方案一:提前创建正确的ES索引映射
ES的字段类型一旦创建就不能直接修改,所以最好提前定义好映射,确保日期字段被识别为date类型。执行下面的ES命令创建索引(如果索引已经存在,先删除或者用reindex迁移数据):
PUT /index_esche { "mappings": { "properties": { "Createdon": { "type": "date", "format": "yyyy-MM-dd'T'HH:mm:ss.SSSZ" }, "Updatedon": { "type": "date", "format": "yyyy-MM-dd'T'HH:mm:ss.SSSZ" }, "Resolvedon": { "type": "date", "format": "yyyy-MM-dd'T'HH:mm:ss.SSSZ" }, "Ticket": { "type": "keyword" } } } }
这个格式和Spark Timestamp默认输出的ISO格式完全匹配,ES会正确解析存储为date类型。之后再运行你的Spark写入代码就没问题了。
3. 方案二:调整Spark写入配置
如果你想让连接器自动处理映射,需要在写入时加上es.mapping.date.format配置,并且确保es.mapping.date.rich的取值正确(小写true也可以,字符串形式没问题)。修改你的代码如下:
spark_df1.write.format("org.elasticsearch.spark.sql") \ .option('es.index.auto.create', 'true') \ .option("es.write.operation", "index") \ .option('es.host','localhost') \ .option('es.mapping.date.rich', "true") \ .option('es.mapping.date.format', "yyyy-MM-dd'T'HH:mm:ss.SSSZ") \ .option('es.mapping.id', 'Ticket') \ .mode("append") \ .save("index_esche/type")
这个配置会告诉连接器把Spark的Timestamp类型按照指定格式映射为ES的date类型,避免转成Long。
4. 处理已有错误数据
如果你的索引里已经有了Long类型的日期数据,需要重新索引这些数据:
- 先创建新的正确映射的索引
- 用ES的
_reindexAPI把旧索引的数据迁移到新索引 - 之后用新索引来查询和写入
验证
完成配置后,重新写入数据,再查询ES的映射,确认这三个字段的类型是date,然后查询数据就能看到正确的日期格式了,而不是Long值。
内容的提问来源于stack exchange,提问作者MOHIT PATNI

