映射是定义文档及其包含的字段的存储和索引方式的过程。
- 两种映射方式
dynamic mapping(动态映射或自动映射)
expllcit mapping(静态映射或手工映射或显示映射)
-
Mapping数据类型
-
Mapping参数
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/removal-of-types.html
Mapping介绍
Mapping 也称之为映射,定义了 ES 的索引结构、字段类型、分词器等属性,是索引必不可少的组成部分。
ES中的mapping有点类似与RDB中“表结构”的概念,在MySQL中,表结构里包含了字段名称,字段的类型还有索引信息等。
在Mapping里也包含了一些属性,比如字段名称、类型、字段使用的分词器、是否评分、是否创建索引等属性,并且在ES中一个字段可以有对个类型。分词器、评分等概念在后面的课程讲解。
查看mapping
GET /index/_mappings
查询该索引的mapping
GET product/_mapping
查询该索引的pricez字段的mapping
GET product/_mapping/field/price
字段数据类型
映射的数据类型也就是 ES 索引支持的数据类型,其概念和 MySQL 中的字段类型相似,但是具体的类型和MySQL 中有所区别,最主要的区别就在于 ES 中支持可分词的数据类型,如:Text 类型,可分词类型是用以支持全文检索的,这也是ES生态最核心的功能。
数字类型
- long:64位有符号整形
- integer:32位有符号整形
- shot:16位有符号整形
- byte:8位有符号整形
- double:双精度64位浮点类型。
- float:单精度64位浮点类型
- half_float:半精度64位浮点类型
- scaled_float:缩放类型浮点数,按固定 double 比例因子缩放
- unsigned_long:无符号64 位整数
基本数据类型
- binary:Base64字符串二进制值
- boolean:布尔类型
- alias:字段别名
keyword类型
-
keyword:适用于索引结构化的字段,可以用于过滤、排序、聚合。keyword类型的字段只能通过精确值(exact value)搜索到。如Id、姓名这类字段应该用keyword。
-
constant_keyword:始终包含相同值的关键字字段
-
wildcard:可针对类似grep的通配符查询优化日志行和类似的关键字值。
关键字字段通常用于排序, 汇总和Term查询,例如term
。
可以查询出来2个
GET product/_search
{"query": {"match": {"name": "xiaomi"}}
}
查询不出来,match--name.keyword,不会被分词,精确查找
GET product/_search
{"query": {"match": {"name.keyword": "xiaomi"}}
}
Dates时间类型
date
:JSON 没有日期数据类型,因此 Elasticsearch 中的日期可以是以下三种
包含格式化日期的字符串,例如“2015-01-01"、“2015/01/01 12:10:30"。
时间戳,表示自"1970年1月1日“以来的毫秒数/秒数。
date_nanos
:此数据类型是对 date 类型的补充。但是有一个重要区别。date 类型存储最高精度为毫秒,而date nanos 类型存储日期最高精度是纳秒,但是高精度意味着可存储的日期范围小,即:从大约1970到2262。
对象类型
- object:非基本数据类型之外,默认的json对象为object类型。用于单个JSON对象
- flattened:单映射对象类型,其值为json类型。允许将整个JSON对象索引为单个字段
- nested:嵌套类型。用于JSON对象数组
- join:父子级关系类型
空间数据类型
- geo-point:纬度/经度点
- geo-shape:用于多边形等复杂形状,例如多边形
- point:笛卡尔坐标点
- shape:笛卡尔任意几何图形
文档排名类型
- dense vector:记录浮点值的密集向量。
- rank feature:记录数字特征以提高查询时的命中率。
- rank features:记录数字特征以提高查询时的命中率。
文本搜索类型
- text:文本类型,全文检索
- annotated-text:索引包含特殊标记的文本(通常用于标识命名实体)
- completion:用于自动补全,即搜索推荐
- search-as-you-type:针对查询优化的文本字段,以实现按需输入的完成
- tocken_count:文本中的标记计数。计算字符串中令牌的数量
其他类型
range(区间类型):integer_range、float_range、long_range、double_range、date_range
IP地址:ip 用于IPv4和IPv6地址
murmur3:在索引时计算值的哈希并将其存储在索引中
percolator:接受来自query-dsl的查询
sparse vector:记录浮点值的稀疏向量。
histogram:histogram 用于百分位数聚合的预聚合数值。
array(数组):在Elasticsearch中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值都必须具有 相同的数据类型。
两种映射类型
-
Dynamic field mapping:自动映射
field typoe field mapping 整数 long s 浮点数 float true/false boolean 日期 date 数组 取决于数组中的第一个有效值 对象 object 字符串 如果不是数字和日期类型,那会被映射为text和keyword两个类型 除了上述字段类型之外,其他类型都必须显示映射,也就是必须手工指定,因为其他类型ES无法自动识别。
PUT test_dynamic_mapping/_doc/1 {"name": "张三 李四 王五","age": 18,"sex": true,"tag": ["tag1","tag2","tag3"],"tag2": [1,2,3] }#查询 mapping GET test_dynamic_mapping/_mapping GET test_dynamic_mapping/_searchGET test_dynamic_mapping/_search {"query": {"match": {"name": "张"}} }
_mapping结果:
{"test_dynamic_mapping" : {"mappings" : {"properties" : {"age" : {"type" : "long"},"name" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"sex" : {"type" : "boolean"},"tag" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"tag2" : {"type" : "long"}}}} }
-
Expllcit field mapping:手动映射
PUT /product
{"mappings": {"properties": {"field": {"mapping_parameter": "parameter_value"}}}
}例子:
PUT test_mapping
{"mappings": {"properties": {"title": {"type" : "text"},"name": {"type": "text", "fields": {"keyword": {"type" : "keyword","ignore_above" : 256}}},"age": {"type" : "text"}}}
}
映射参数
① index:是否对创建对当前字段创建倒排索引,默认true,如果不创建索引,该字段不会通过索引被搜索到,但是仍然会在source元数据中展示
#创建索引映射
PUT test_params
{"mappings": {"properties": {"test_index": {"type": "text","index": false}}}
}
#插入数据
PUT test_params/_doc/1
{"test_index": "elastic"
}
#在_source可以看到test_index
GET test_params/_search
#match查询,不能查询,提示failed to create query: Cannot search on field [test_index] since it is not indexed
GET test_params/_search
{"query": {"match": {"test_index": "elastic"}}
}
#删除索引
DELETE test_params
② analyzer:指定分析器(character filter、tokenizer、Token filters)。
③ boost:对当前字段相关度的评分权重,默认1
④ coerce:是否允许强制类型转换 true “1”=> 1 false “1”=< 1
⑤ copy_to:该参数允许将多个字段的值复制到组字段中,然后可以将其作为单个字段进行查询
⑥ doc_values:为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc值以节省磁盘空间(不支持text和annotated_text)
⑦ dynamic:控制是否可以动态添加新字段
1) true 新检测到的字段将添加到映射中。(默认)
2) false 新检测到的字段将被忽略。这些字段将不会被索引,因此将无法搜索,但仍会出现在_source返回的匹配项中。这些字段不会添加到映射中,必须显式添加新字段。
3) strict 如果检测到新字段,则会引发异常并拒绝文档。必须将新字段显式添加到映射中
⑧ eager_global_ordinals:用于聚合的字段上,优化聚合性能。
1) Frozen indices(冻结索引):有些索引使用率很高,会被保存在内存中,有些使用率特别低,宁愿在使用的时候重新创建,在使用完毕后丢弃数据, Frozen indices的数据命中频率小,不适用于高搜索负载,数据不会被保存在内存中,堆空间占用比普通索引少得多,Frozen indices是只读的,请求可能是秒级或者分钟级。*eager_global_ordinals不适用于Frozen indices*
⑨ enable:是否创建倒排索引,可以对字段操作,也可以对索引操作,如果不创建索引,让然可以检索并在_source元数据中展示,谨慎使用,该状态无法 修改。
PUT my_index{"mappings": {"enabled": false}}
⑩ fielddata:查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中
⑪ fields:给field创建多字段,用于不同目的(全文检索或者聚合分析排序)
⑫ format:格式化
"date": {"type": "date","format": "yyyy-MM-dd"}
⑬ ignore_above:超过长度将被忽略,不是截断(用match查不到了)。
⑭ ignore_malformed:忽略类型错误
⑮ index_options:控制将哪些信息添加到反向索引中以进行搜索和突出显示。仅用于text字段
⑯ Index_phrases:提升exact_value查询速度,但是要消耗更多磁盘空间
⑰ Index_prefixes:前缀搜索
1) min_chars:前缀最小长度,>0,默认2(包含)
2) max_chars:前缀最大长度,<20,默认5(包含)
⑱ meta:附加元数据
⑲ normalizer:分词器的时候
⑳ norms:是否禁用评分(在filter和聚合字段上应该禁用)。
21 null_value:为null值设置默认值
22 position_increment_gap:
23 proterties:除了mapping还可用于object的属性设置
24 search_analyzer:设置单独的查询时分析器:
指的是类似query–match这里查询用的分词器。当然你可以search_analyzer指定english,analyzer指定ik。
25 similarity:为字段设置相关度算法,支持BM25、claassic(TF-IDF)、boolean
26 store:设置字段是否仅查询
**27 term_vector:**运维参数
Text和Keyword类型
Text类型
当一个字段是要被全文搜索的,比如 Email 内容、产品描述,这些字段应该使用 text 类型。设置 text 类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。
text类型的字段不用于排序,很少用于聚合。
注意事项:
- 适用于全文检索:如match 查询
- 文本字段会被分词
- 默认情况下,会创建倒排索引
- 自动映射器会为 Text 类型,创建 Keyword 字段
{"test_mapping" : {"mappings" : {"properties" : {"name" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}}}}}
}
Keyword类型
Keyword 类型适用于不分词的字段,如姓名、ld、数字等。如果数字类型不用于范围查找,用 Keyword 的性能要高于数值类型。
如当使用 keyword 类型查询时,其字段值会被作为一个整体,并保留字段值的原始属性。
GET test_mapping/_search
{"query": {"match": {"name.keyword": "sss"}}
}
注意事项:
- Keyword 不会对文本分词,会保留字段的原有属性,包括大小写等
- Keyword 仅仅是字段类型,而不会对搜索词产生任何影响
- Keyword 一般用于需要精确查找的字段,或者聚合排序字段
- Keyword 通常和 Term 搜索一起用 (会在DSL 中提到)
- Keyword 字段的 ignore_above 参数代表其截断长度,默认256,如果超出长度,字段值会被忽略(用match查不到了),而不是截断。
映射模板
之前讲过的映射类型或者字段参数,都是为确定的某个字段而声明的,如果希望对符合某类要求的特定字段制定映射,就需要用到映射模板: Dynamic templates。
映射模板有时候也被称作:自动映射模板、动态模板等。
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/dynamic-templates.html
dynamic_templates 针对的是字段
index_templates 针对的是索引
语法:
"dynamic_templates": [{"my_template_name": { ... match conditions ... "mapping": { ... } }},...]
Conditions参数
- match_mapping_type:主要用于对数据类型的匹配
- match 和unmatch:用于对字段名称的匹配
例子:
#是long类型的,给声明为integer类型
#是string类型 并且 以num_开头的 并且 不能以_text结尾的,给声明为keyword类型
PUT test_dynamic_template
{"mappings": {"dynamic_templates": [{"integers": {"match_mapping_type": "long","mapping": {"type": "integer"}}},{"strings": {"match_mapping_type": "string","match": "num_*","unmatch": "*_text","mapping": {"type": "keyword"}}}]}
}PUT test_dynamic_template/_doc/1
{"test1": 1212,"num_text": "abc","num_sss": "ddd","aa_text": "aaa"
}GET test_dynamic_template/_mapping
_mapping结果:test1是integer类型,num_sss是keyword类型
{"test_dynamic_template" : {"mappings" : {"dynamic_templates" : [{"integers" : {"match_mapping_type" : "long","mapping" : {"type" : "integer"}}},{"strings" : {"match" : "num_*","unmatch" : "*_text","match_mapping_type" : "string","mapping" : {"type" : "keyword"}}}],"properties" : {"aa_text" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"num_sss" : {"type" : "keyword"},"num_text" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"test1" : {"type" : "integer"}}}}
}