mapping就是Elasticsearch数据字段field的type元数据,Elasticsearch在创建索引的时候,dynamic mapping会自动为不同的数据指定相应mapping,mapping中包含了字段的类型、搜索方式(exact value或者full text)、分词器等。简单点理解,mapping类似于SQL中的表结构。
查看mapping

  1. GET /{index_name}/_mappings

1. Dynamic mapping

filed mapping 搜索方式
“elasticsearch” text full text
“elasticsearch” keyword exact value
123456 long
exact value
3.1415926 double exact value
true/false boolean exact value
2020-05-20 / 2020-05-20 11:21:30 date exact value

为啥price字段是long类型而不是integer?因为es的mapping_type是由JSON分析器检测数据类型,而JSON没有隐式类型转换,所以dynamic mapping会选择一个比较宽的数据类型。

Dynamic mapping的3种模式

dynamic=”true” dynamic=”false” dynamic=”strict”
文档可索引 Y Y N
字段课索引 Y N N
Mapping被更新 Y N N
  1. //1. 创建索引
  2. PUT movies
  3. //2. 设置dynamic位严格模式
  4. PUT movies/_mapping
  5. {
  6. "dynamic":"strict" //
  7. }
  8. //3. 获取mapping
  9. GET movies

image.png

2. Elasticsearch的搜索方式

  • exact value 精确匹配:

在倒排索引过程中,分词器会将field作为一个整体创建到索引中,

  • full text 全文检索:

分词、近义词同义词、混淆词、大小写、词性、过滤、时态转换等(normaliztion)

3. Elasticsearch的数据类型

分类 类型 说明
基础类型 long
integer
short
byte
double
float
half_float
scaled_float
在满足需求的情况下,尽可能选择范围小的数据类型
keyword keyword类型的字段只能通过精确值(exact value)搜索到,所以适用于索引结构化的字段,可以用于过滤、排序、聚合。keyword类型的字段只能通过精确值(exact value)搜索到。另外:_id应该用keyword
text 当一个字段是要被全文搜索的,比如Email内容、产品描述,这些字段应该使用text类型。设置text类型以后,字段内容会被分成一个一个词后生成倒排索。
text类型的字段不用于排序,也很少用于聚合。(解释一下为啥不会为text创建索引:字段数据会占用大量堆空间,尤其是在加载高基数text字段时。字段数据一旦加载到堆中,就在该段的生命周期内保持在那里。同样,加载字段数据是一个昂贵的过程,可能导致用户遇到延迟问题。这就是默认情况下禁用字段数据的原因)
有时,在同一字段中同时具有全文本(text)和关键字(keyword)版本会很有用:一个用于全文本搜索,另一个用于聚合和排序。
date 日期类型
boolean 布尔类型
binary 二进制
integer_range
float_range
long_range
double_range
date_range
区间类型
复杂类型 object 用于单个JSON对象
nested 用于JSON对象数组
地理位置 geo-point 纬度/经度积分
geo-shape 用于多边形等复杂形状
特有类型 IP ip 用于IPv4和IPv6地址
completion 提供自动完成建议
tocken_count 计算字符串中令牌的数量
murmur3 在索引时计算值的哈希并将其存储在索引中
percolator 接受来自query-dsl的查询
join 为同一索引内的文档定义父/子关系
annotated-text 索引包含特殊标记的文本(通常用于标识命名实体)

4. indexTemplate 和DynamicTemplate

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/indices-templates.html

https://www.elastic.co/guide/en/elasticsearch/reference/7.1/dynamic-mapping.html

5. Demo

创建mapping

模板

  1. PUT /{index_name}
  2. {
  3. "mappings": {
  4. "properties": {
  5. "{field_name}": {
  6. "{mapping_parameter}": "{parameter_value}",
  7. "{mapping_parameter}": "{parameter_value}"
  8. },
  9. "{field_name}": {
  10. "{mapping_parameter}": "{parameter_value}",
  11. "{mapping_parameter}": "{parameter_value}"
  12. }
  13. }
  14. }
  15. }

{``mapping_parameter}{parameter_value} 可选内容有

{mapping_parameter} {parameter_value} 默认 解释
type #5.2 Elasticsearch的数据类型
index true/false true 是否对创建对当前字段创建索引,默认true,如果不创建索引,该字段不会通过索引被搜索到,但是仍然会在source元数据中展示
analyzer character filter
tokenizer
token filters
指定分析器
boost 1 对当前字段相关度的评分权重
coerce true/false 数据被是否允许强制类型转换
copy_to 其他字段的字段名 从其他字段copy值
doc_values true/false true 正排索引:为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc值以节省磁盘空间(不支持text和annotated_text)
dynamic true 新检测到的字段将添加到映射中。(默认)
false 新检测到的字段将被忽略。这些字段将不会被索引,因此将无法搜索,但仍会出现在_source返回的匹配项中。这些字段不会添加到映射中,必须显式添加新字段。
strict 如果检测到新字段,则会引发异常并拒绝文档。必须将新字段显式添加到映射中
eager_global_ordinals true/false frozen indices(冻结索引):有些索引使用率很高,会被保存在内存中,有些使用率特别低,宁愿在使用的时候重新创建,在使用完毕后丢弃数据,Frozen indices的数据命中频率小,不适用于高搜索负载,数据不会被保存在内存中,堆空间占用比普通索引少得多,Frozen indices是只读的,请求可能是秒级或者分钟级。eager_global_ordinals不适用于Frozen indices
enable 是否创建倒排索引,可以对字段操作,也可以对索引操作,如果不创建索引,让然可以检索并在_source元数据中展示,谨慎使用,该状态无法修改。
fielddata 查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中
fields 给field创建多字段,用于不同目的(全文检索或者聚合分析排序)
format yyyy-MM-dd 格式化
ignore_above 超过长度将被忽略
ignore_malformed true/false 忽略类型错误
index_options 控制将哪些信息添加到反向索引中以进行搜索和突出显示。仅用于text字段
Index_phrases 提升exact_value查询速度,但是要消耗更多磁盘空间
Index_prefixes 前缀搜索
min_chars:前缀最小长度,>0,默认2(包含)
max_chars:前缀最大长度,<20,默认5(包含)
“index_prefixes”: {
“min_chars” : 1,
“max_chars” : 10
}
meta ① 附加元数据
normalizer
norms true/false 是否禁用评分(在filter和聚合字段上应该禁用)。
null_value 为null值设置默认值
position_increment_gap
proterties 除了mapping还可用于object的属性设置
search_analyzer
similarity BM25、claassic、boolean 为字段设置相关度算法
store 设置字段是否仅查询
term_vector

search_analyzer:设置单独的查询时分析器:

  1. PUT /{index_name}
  2. {
  3. "settings": {
  4. "analysis": {
  5. "filter": {
  6. "autocomplete_filter": {
  7. "type": "edge_ngram",
  8. "min_gram": 1,
  9. "max_gram": 20
  10. }
  11. },
  12. "analyzer": {
  13. "autocomplete": {
  14. "type": "custom",
  15. "tokenizer": "standard",
  16. "filter": [
  17. "lowercase",
  18. "autocomplete_filter"
  19. ]
  20. }
  21. }
  22. }
  23. },
  24. "mappings": {
  25. "properties": {
  26. "text": {
  27. "type": "text",
  28. "analyzer": "autocomplete",
  29. "search_analyzer": "standard"
  30. }
  31. }
  32. }
  33. }
  34. PUT {index_name}/_doc/{index_id}
  35. {
  36. "text": "Quick Brown Fox"
  37. }
  38. GET {index_name}/_search
  39. {
  40. "query": {
  41. "match": {
  42. "text": {
  43. "query": "Quick Br",
  44. "operator": "and"
  45. }
  46. }
  47. }
  48. }

一个类似于这样的SQL建表语句

  1. create table user
  2. (
  3. id int auto_increment primary key,
  4. name varchar(128) null comment '用户名称',
  5. address varchar(256) null comment '用户详细地址',
  6. amount decimal(19, 2) null comment '总账户余额',
  7. create_time timestamp null comment '创建时间',
  8. is_del int null comment '是否删除(1是0否)',
  9. account varchar(128) null comment '登录账号'
  10. )
  11. comment '用户表' charset = utf8;

Elasticsearch创建

  1. PUT /user
  2. {
  3. "mappings": {
  4. "properties": {
  5. "id":{
  6. "type": "integer"
  7. },
  8. "name":{
  9. "type": "text"
  10. },
  11. "address":{
  12. "type": "text"
  13. },
  14. "amount":{
  15. "type": "double"
  16. },
  17. "create_time":{
  18. "type": "date"
  19. },
  20. "is_del":{
  21. "type": "boolean"
  22. },
  23. "account":{
  24. "type": "text"
  25. }
  26. }
  27. }
  28. }