项目中遇到ES中的时间格式导入HIVE中,出现异常。
今天晚上有空研究了一下Elasticsearch-hadoop 源码,发现HiveValueReader用的是下面这个方法在解析时间字符串
DatatypeConverter.parseDateTime(value)
没有用到ES中我们指定的时间格式。
curl -XPUT 'localhost:9200/myindex?pretty' -H 'Content-Type: application/json' -d' { "mappings": { "myindex": { "_all": { "enabled": false }, "properties": { "id": { "type": "keyword" }, "created": { "type": "date", "format": "yyyyMMddHHmmssSSS||epoch_millis" } } } } } '
解决方法:
在HIVE中指定时间格式,并自定义自己的reader. 这里的时间格式是自定义个属性。
CREATE EXTERNAL TABLE myindex (id STRING, created timestamp ) STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' TBLPROPERTIES('es.resource' = 'myindex/myindex', 'es.date.format' = 'yyyyMMddHHmmssSSS', 'es.ser.reader.value.class' = 'gez.es.hadoop.reader.EsValueReader');
自定义的reader
package gez.es.hadoop.reader; import java.sql.Timestamp; import java.util.Date; import javax.xml.bind.DatatypeConverter; import org.apache.hadoop.hive.serde2.io.TimestampWritable; import org.elasticsearch.hadoop.cfg.Settings; import org.elasticsearch.hadoop.hive.HiveValueReader; import jodd.util.StringUtil; public class EsValueReader extends HiveValueReader{ private String dateFormat; org.apache.hadoop.io.Writable f; @Override public void setSettings(Settings settings) { super.setSettings(settings); dateFormat = settings.getProperty("es.date.format"); } @Override protected Object parseDate(String value, boolean richDate) { Date d = null; System.out.println(String.format("value : %s, dataFormat: %s ", value, dateFormat)); if(StringUtil.isNotEmpty(dateFormat)) { d = DateUtil.parseDate(value, dateFormat); } else { d = DatatypeConverter.parseDateTime(value).getTime(); } return (richDate ? new TimestampWritable(new Timestamp(d.getTime())) : parseString(value)); } public static void main(String[] args) { } }
新jar 需要添加到HIVE的lib
运行结果如下: