ElasticSearch中date类型是个很重要的类型。在聚合、排序、和kibana等结合使时都需要date类型。但在某些依赖es动态映射出index,type及字段类型时,时间字段值为时间戳可能出现一些问题:
- 动态映射:
- 在开启自动创建索引(action.auto_create_index)下,传入一个json字符串进行保存时
- 在某个字段第一次出现时,如果之前没有定义过映射,ES会自动检测它可能满足的类型,然后创建对应的映射。
- 比如, integer -> long ;string -> date 或string (“yyyy-dd-mm”等字段会转成date )
- 官网对于自动映射的介绍https://www.elastic.co/guide/en/elasticsearch/reference/5.6/dynamic-field-mapping.html#date-detection
这就有个问题,如果json中,时间字段是以 秒时间戳 或者 毫秒时间戳生成的,就无法转换为date,这时可以利用索引模板解决此问题:
_template/template1 PUT{
{
"template": "dealer",
"order": 1,
"mappings": {
"_default_": {
"properties": {
"create_time": {
"type": "date",
"format": "epoch_second"
}
}
}
}
}
}
/**
template1 --- 创建模板名
"template": "dealer" --- 模板匹配index='dealer',也可以使用-*等匹配多个索引
设置create_time 字段为date,为秒时间戳,还可以设置为epoch_millis 毫秒时间戳
*/
测试:
- 1.设定模板,匹配index=’public_sentiment’,create_time字段支持秒时间戳,create_time_millis支持毫秒时间戳
- 2.删除index=public_sentiment
- 3.插入测试数据,包含4个字段,create_time,create_time_none,create_time_millis,create_time_millis_none
@Test
public void testInsert(){
long time_millis = System.currentTimeMillis();
String timestamp = String.valueOf(time_millis/1000);
long time = Integer.valueOf(timestamp);
String index="public_sentiment";
String type="public_sentiment-2018";
String json="{\"type\":\"mouth_quality\"," +
"\"create_time_none\":"+time+"," +
"\"create_time\":"+time+"," +
"\"create_time_millis\":"+time_millis+"," +
"\"create_time_millis_none\":"+time_millis+"}";
ESUtil.index(index, type, json,null);
}
- 4.验证插入数据后,自动创建index,且create_time,create_time_millis 为date类型,create_time_none,create_time_millis_none为long类型
- 5.在kibana中,可以扫描到此date类型
- 6.时间排序起作用