Elasticsearch重新索引时能否转换日期并处理异常格式数据?
Elasticsearch 日期字段转换异常处理方案
问题背景
原索引中dueDate字段为text类型,修改为date类型并指定格式dd.MM.yyyy.、配置copy_to: _content后,重新索引时因部分数据格式异常(如15.09.2021. 06:49:18)抛出mapper_parsing_exception,多数数据格式符合要求,仅少数异常数据影响进程。
原mapping配置
"dueDate": { "type": "text" }
修改后的mapping配置
"dueDate": { "type": "date", "format": "dd.MM.yyyy.", "copy_to": "_content" }
报错信息
{"type":"mapper_parsing_exception","reason":"failed to parse [dueDate]","caused_by":{"type":"illegal_argument_exception","reason":"Invalid format: \"15.09.2021. 06:49:18\" is malformed at \" 06:49:18\""}},"status":400}
解决方案
1. 自动提取异常数据中的日期部分
通过Reindex API配合Painless脚本,对异常格式的dueDate进行预处理,提取有效日期部分后再写入新索引。
方案1:简单截取(适配带时间后缀的异常格式)
针对类似15.09.2021. 06:49:18的格式,直接截取空格前的日期部分,确保符合目标格式:
{ "source": { "index": "原索引名称" }, "dest": { "index": "新索引名称" }, "script": { "source": """ String dueDate = ctx._source.dueDate; if (dueDate != null) { // 截取空格前的日期部分 if (dueDate.contains(" ")) { dueDate = dueDate.split(" ")[0]; } // 确保格式以.结尾(匹配目标mapping要求) if (!dueDate.endsWith(".")) { dueDate += "."; } ctx._source.dueDate = dueDate; } """, "lang": "painless" } }
方案2:多格式解析(更严谨)
通过定义多种日期格式,尝试解析不同格式的dueDate,成功后统一转换为目标格式;无法解析的可选择移除字段避免报错:
{ "source": { "index": "原索引名称" }, "dest": { "index": "新索引名称" }, "script": { "source": """ String dueDateStr = ctx._source.dueDate; if (dueDateStr != null) { // 定义需要兼容的日期格式 def formatters = [ DateTimeFormatter.ofPattern("dd.MM.yyyy. HH:mm:ss"), DateTimeFormatter.ofPattern("dd.MM.yyyy.") ]; LocalDate date = null; // 循环尝试解析 for (formatter in formatters) { try { date = LocalDate.parse(dueDateStr, formatter); break; } catch (Exception e) { // 解析失败,继续尝试下一种格式 } } if (date != null) { // 转换为目标格式dd.MM.yyyy. ctx._source.dueDate = date.format(DateTimeFormatter.ofPattern("dd.MM.yyyy.")); } else { // 无法解析时移除字段,避免索引报错 ctx._source.remove("dueDate"); } } """, "lang": "painless" } }
2. 最后手段:忽略异常数据
若无需保留异常数据的日期信息,可通过配置ignore_malformed让Elasticsearch跳过无法解析的字段值,不中断整个索引过程。
修改新索引的mapping,添加ignore_malformed: true:
"dueDate": { "type": "date", "format": "dd.MM.yyyy.", "copy_to": "_content", "ignore_malformed": true }
配置后,Elasticsearch会忽略所有不符合格式的dueDate值,正常索引其他数据,不会抛出解析异常。
内容的提问来源于stack exchange,提问作者vr552
相关产品推荐
相关产品推荐

