Elasticsearch动态映射与日期类型
JSon没有日期类型,但Elasticsearch能自动为我们映射日期字段。如果结合日期字段命名约定可以帮我我们准确实现动态映射。
1. 动态映射
Elasticsearch的动态映射特性可以实现根据字段值自动映射字段类型(缺省类型),因此无需显示定义如何索引、存储字段,Elasticsearch通过检查JSon属性的内容自动推断类型。请看示例:
如果之前没有索引myindex
,Elasticsearch会帮助我们做下列工作:
POST /myindex/_doc
{
"content": "Hello World!",
"postDate": "2009-11-15T14:12:12"
}
- 创建索引
myindex
,包括两个字段content和postDate - 使用json对象内容增加一个文档
我们来看看Elasticsearch为我们自动创建索引的映射:
GET myindex/_mapping
结果如下:
{
"myindex" : {
"mappings" : {
"properties" : {
"content" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"postDate" : {
"type" : "date"
}
}
}
}
}
content类型默认为text,同时生成content.keyword为keyword类型,同时可以实现全文检索和精确检索。postDate为Date类型。
如果我们通过DELETE /myindex
删除上面myindex,而用下面的内容添加索引:
POST /myindex/_doc
{
"content": "1985-12-24",
"postDate": "2009-11-15T14:12:12"
}
再次查看映射:
{
"myindex" : {
"mappings" : {
"properties" : {
"content" : {
"type" : "date"
},
"postDate" : {
"type" : "date"
}
}
}
}
}
elasticsearch把content字段也推断了日期类型。如果现在插入原来的文档会报异常:
POST /myindex/_doc
{
"content": "Hello World!",
"postDate": "2009-11-15T14:12:12"
}
"caused_by": {
"type": "illegal_argument_exception",
"reason": "failed to parse date field [Hello World!] with format [strict_date_optional_time||epoch_millis]"
}
...
我们试图将字符串值插入到映射为日期的字段中,ElasticSearch自然不允许。
虽然这种情况不太可能发生,但发生时会非常恼人,只能通过将所有内容重新索引到新索引中来解决。但幸运的是有许多可能的解决方案。
2. 禁止日期推断
首先我们可以禁用动态映射时日期推断。下面示例显示禁止日期推断:
PUT /myindex
{
"mappings": {
"date_detection": false
}
}
然后在插入文档:
POST /myindex/_doc
{
"content": "1985-12-24",
"postDate": "2009-11-15T14:12:12"
}
再查看映射结果为:
{
"myindex" : {
"mappings" : {
"date_detection" : false,
"properties" : {
"content" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"postDate" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
现在两个字段内容都包括日期,但都被映射为text类型,并且有子类型keyword。但postDate也被映射为字符串,失去了日期类型的能力。
我们现在显示指定映射日期类型;
PUT /myindex
{
"mappings": {
"date_detection": false,
"properties": {
"postDate": {
"type": "date"
}
}
}
}
如果我们再次插入上面问题json内容,映射类型与我们期望的一致。但这种方法不灵活,尤其当有很多字段且有些字段之前并不能确定其类型时。
3. 使用命名规范映射日期字段
另外一种方法禁用日期推断同时显示映射特定字段作为日期类型:
PUT /myindex
{
"mappings": {
"date_detection": false,
"dynamic_templates": [
{
"dates": {
"match": ".*Date|date",
"match_pattern": "regex",
"mapping": {
"type": "date"
}
}
}
]
}
}
比较两者方法有差异。和前面一样也禁用日期推断,但之后不再提供属性映射,而是提供提供基于名称dates
动态映射。在名称动态映射中指定正则表达式,符合表达式规范则使用日期类型。
使用这种方法,所有字符串不再会被映射为日期类型,除了其名称以Date结尾,如postDate,updateDate等。
这样虽好,但不能把以Date结尾字段的值设置非日期字符串。但不能否认这种方法还是相对比较灵活,在实际应用中比较可行,毕竟对字段明确一些命名规范也属于数据库设计的一部分。
4. 总结
本文介绍了Elasticsearch的动态映射,并通过如何准确推断日期类型示例进行说明,其他类型也可以使用类似方法。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/105324174