动态映射
elasticsearch 最重要的功能之一是它试图摆脱你的方式,让你尽快开始探索你的数据。要索引文档,你不必首先创建索引,定义映射类型和定义字段,你只需索引文档、索引、类型和字段将自动生效:
例如:
它将创建data索引,_doc 映射类型和 count字段使用数据类型调用的字段long
PUT data/_doc/1
{ "count": 5 }
自动检测和添加新字段称为 动态映射。可以自定义你动态映射规则以满足你的目的:
一、动态字段映射
默认情况下,当咋文档中找到以前未见过的字段时,elasticsearch 会将新字段添加到类型映射中。object 通过将 dynamic 参数设置为 false(忽略新字段)或 strict(如果遇到未知字段,则抛出异常),可以在文档级别禁用此行为哦。
假设 dynamic 启用了字段映射,则使用一些简单的规则来确定字段应具有的数据类型:
json datatype elasticsearch datatype
null no field is added
true or false boolean field
floatiing point number float field
integer long field
object object field
array 取决于array中的第一个非空值
string 任一date字段(如果该值船队日期检测)、一个double或long字段(如果这个值通过数字检测)或text字段,具有keyword字段
这些是动态检测的唯一字段数据类型。必须显式映射所有其他数据类型。
除了下面列出的选项外,还可以进一步自定义动态字段映射规则
1、日期检测
如果 date_detection 启用(默认),则检查新字符串字段以查看其内容是否与指定的任何日期模式匹配 dynamic_data_formats 。如果找到匹配项,date则添加具有相应格式的新字段。
dynamic_date_formats 默认的值为:
[ “strict_date_optional_time”,”yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z”]
例如:
下面 create_date 字段已添加为具有以下内容的date字段格式:”yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z”
PUT my_index/_doc/1
{
"create_date": "2015/09/02"
}
禁用日期检测
可以通过设置 date_detection 为 false:禁用动态日期检测
下面的 create 字段已添加为 text 字段
PUT my_index
{
"mappings": {
"_doc": {
"date_detection": false
}
}
}
PUT my_index/_doc/1
{
"create": "2015/09/02"
}
自定义检测到的日期格式
或者,dynamic_date_formats 可以自定义以支持你的日期格式:
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_date_formats": ["MM/dd/yyyy"]
}
}
}
PUT my_index/_doc/1
{
"create_date": "09/25/2015"
}
2、数字检测
虽然JSON支持本机浮点和整数数据类型,但某些应用程序或语言有时可能将数字呈现为字符串。通常,正确的解决方案是显式映射这些字段,但可以启用数字检测(默认情况西甲禁用)以自动执行此操作:
将 my_float 字段将添加为 float 字段
将 my_integer 字段将添加为 long 字段
PUT my_index
{
"mappings": {
"_doc": {
"numeric_detection": true
}
}
}
PUT my_index/_doc/1
{
"my_float": "1.0",
"my_integer": "1"
}
二、动态模版
自定义规则,用于配置动态添加字段的映射
动态模版允许你定义可应用于动态添加字段的自定义映射,具体取决于:
- elasticsearch 检测到的数据类型 match_mapping_type
- 字段的名称,带 match 和 unmatch 或 match_pattern
- 字段的完整虚线路径,带 path_match 和 path_unmatch
原始字段名称 {name} 和检测到的数据类型 { dynamic_type } 模版变量可以在映射规范中用作占位符。
仅当字段包含具体值时才会添加动态字段映射,不包含空数组或非空数组。这意味着如果 null_value 在a中使用该选项 dynamic_template,则仅在具有该最短的具体值的第一个文档已被索引之后才应用该选项。
动态模版被指定为命名对象的数组
1、模版名称可以是任何字符串值
2、匹配条件可以包括:match_mapping_type、match、match_pattern、umatch、path_match、path_unmatch
"dynamic_templates": [
{
"my_template_name": {
... match conditions ...
"mapping": { ... }
}
},
...
]
模版按顺序处理,第一个匹配到的模版获胜。通过 put 映射 API 放置新的动态模版时,将覆盖所有现有模版,这允许动态模版在最初添加后重新排序或删除。
1、match_mapping_type
match_mapping_type 是 json 解析器检测到的数据类型。由于 JSON 不允许区分 long 从一个integer 或 doube 从 float,它总是会选择更广泛的数据类型。即 long 对于整数和 double 浮点数。
可以自动检测以下数据类型:
- boolean:true 或 false 的布尔值
- date:当日期检测被使能和一个串中发现匹配任何配置的日期格式
- double:对于带小数部分的睡姿
- long:对于没有小数部分的数字
- object:对象,也称为哈希
- string:字符串
当然,* 也可用于匹配所有数据类型
例如,如果我们希望将所有整数字段映射为integer而不是long,并将所有string字段映射为text和keyword,那么可以使用以下模板:
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"integers": {
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
},
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
}
}
PUT my_index/_doc/1
{
"my_integer": 5,
"my_string": "Some string"
}
该示例中:
将 my_integer 字段映射为 integer
将 my_string 字段映射为 text,keyword 具有多字段
match and unmatch
match 参数使用模式匹配字段名称,同时unmatch使用模式排除匹配的字段match
下面的示例匹配名称以long_开头的所有字符串字段(除了以_text结尾的字符串字段之外),并将它们映射为long字段
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"longs_as_strings": {
"match_mapping_type": "string",
"match": "long_*",
"unmatch": "*_text",
"mapping": {
"type": "long"
}
}
}
]
}
}
}
PUT my_index/_doc/1
{
"long_num": "5",
"long_text": "foo"
}
该 long_num 字段映射为 long
该 long_text 字段使用默认 string
match_pattern
match_pattern 参数定义正则,并通过match进行正则匹配
"match_pattern": "regex",
"match": "^profit_\d+$"
path_match and path_unmatch
在 path_match 与 path_unmatch 参数的工作方式与 match 和 unmatch 相同。但是对字段的完整虚线路径进行操作,而不仅仅是最终名称,例如some_object.*.some_field。
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"full_name": {
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping": {
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
}
PUT my_index/_doc/1
{
"name": {
"first": "Alice",
"middle": "Mary",
"last": "White"
}
}
{name} and {dynamic_type}
在字段名称和检测动态类型的映射中替换{name}和{dynamic_type}占位符。下面的示例设置所有字符串字段以使用与字段同名的分析器,并禁用所有非字符串字段的doc_.
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"named_analyzers": {
"match_mapping_type": "string",
"match": "*",
"mapping": {
"type": "text",
"analyzer": "{name}"
}
}
},
{
"no_doc_values": {
"match_mapping_type":"*",
"mapping": {
"type": "{dynamic_type}",
"doc_values": false
}
}
}
]
}
}
}
PUT my_index/_doc/1
{
"english": "Some English text",
"count": 5
}
english 字段被映射为带有 english annalyzer 的字符串字段。
count 字段被映射为具有 doc_values disabled 的 long 字段。
模版示例
以下是一些可能有有用的动态模版示例:
结构化搜索
默认情况下,elasticsearch 会将字符串字段映射为 text 具有子 keyword 字段的字段。但是,如果你只是对结构化内容编制索引而对全文搜索不感兴趣,则可以使用 elasticsearch 仅将你的字段映射为 keyword。请注意,这意味着为了搜索这些字段,你必须搜索与索引完全相同的值。
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
}
text 仅用于字符串映射
与前面的示例相反,如果你在字符串字段中唯一关心的是全文搜索,并且如果你不打算在字符串字段上运行聚合,排序或精确搜索,那么你可以告诉 elasticsearch 仅将其映射为文本字段(这是5.0之前的默认行为)
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"strings_as_text": {
"match_mapping_type": "string",
"mapping": {
"type": "text"
}
}
}
]
}
}
}
禁用 norms
norms 是评分时间得分的因素。如果不关心评分(例如,如果您从不按评分对文档进行排序),则可以禁用这些评分因子在索引中的存储并节省一些空间。
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"norms": false,
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
}
}
子 keyword 字段出现在该模板中,与动态映射的默认规则一致。当然,如果您不需要它们,因为不需要在这个字段上执行精确的搜索或聚合,那么可以按照前面小节中所描述的那样删除它
时间序列
使用Elasticsearch进行时间序列分析时,通常会有许多数字字段,您经常会聚合在这些数字字段上但从不过滤。在这种情况下,您可以禁用这些字段的索引以节省磁盘空间,也可以获得一些索引速度
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"unindexed_longs": {
"match_mapping_type": "long",
"mapping": {
"type": "long",
"index": false
}
}
},
{
"unindexed_doubles": {
"match_mapping_type": "double",
"mapping": {
"type": "float",
"index": false
}
}
}
]
}
}
}
说明:索引模版允许你配置新索引的默认映射,设置和别名,无论是自动创建还是显式创建
官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-mapping.html