升级elasticsearch-spark后日期字段写入ES报mapper_parsing_exception如何解决
问题根因
elasticsearch-spark 7.7及之后的版本调整了日期类型的序列化逻辑,和你之前用的7.6.0版本核心差异为:
- 旧版本会自动将Long类型的毫秒时间戳,按照ES索引映射的date格式自动转换为对应格式的字符串后写入
- 新版本默认会将Long类型的字段值直接作为字符串传递给ES,而你的ES映射只配置了
yyyy-MM-dd一种日期解析格式,无法识别数值型的时间戳字符串,因此抛出解析异常
解决方案
你可以根据业务场景任选以下一种方式处理:
- 调整ES索引日期映射(推荐,改造成本最低)
给my_partition_key字段的format配置增加毫秒时间戳的支持,调整后的映射如下:
"my_partition_key": { "format": "yyyy-MM-dd||epoch_millis", "type": "date" }
配置后ES可以同时支持yyyy-MM-dd格式的字符串、毫秒级Long时间戳两种输入,不需要修改Spark侧的任何代码。
- Spark侧提前转换字段格式
在写入ES之前,将Long类型的时间戳转换为yyyy-MM-dd格式的字符串,Spark SQL转换示例:
// 假设ds是你的原始数据集 import org.apache.spark.sql.functions._ val processedDs = ds.withColumn("my_partition_key", date_format(from_unixtime(col("my_partition_key") / 1000), "yyyy-MM-dd") )
转换完成后再写入ES即可。
- 通过elasticsearch-spark配置指定日期转换规则
在写入ES的配置中添加es.date.format参数,指定连接器自动将日期/时间戳转换为指定格式:
ds.write .format("org.elasticsearch.spark.sql") .option("es.nodes", "你的ES地址") .option("es.date.format", "yyyy-MM-dd") // 新增这行配置 .save("你的索引名")
这个配置会让连接器自动把Long类型的时间戳转换为yyyy-MM-dd格式的字符串后写入,不需要修改映射和业务逻辑。
内容的提问来源于stack exchange,提问作者Naresh G
相关产品推荐
相关产品推荐

