映射mapping操作

1991/6/26 基础

# 1. 什么是Mapping

Mapping 类似MYSQL中的表结构(schema) ,其作用如下

  • 定义索引中的字段的名称
  • 定义字段的数据类型,例如字符串(text、keyword)、数值型(integer,float..)
  • 字段,倒排索引的相关配置,比如设置某个字段为不被索引、记录 position 等

从ElasticSearch7.0 之后的版本,一个索引只有一个Type(_doc),7.0 开始,不需要在 Mapping 定义中指定 type信息。

# 2. 都有哪些类型

描述 类型
字符串 text, keyword
数值型 long, integer, short, byte, double, float, half_float, scaled_float
布尔型 boolean
日期型 date, date_nanos
二进制 binary
范围型 integer_range, float_range, long_range, double_range, date_range
对象类型 object
嵌套类型 nested
地理坐标类型 geo_point
地理形状类型 geo_shape
IP地址类型 IP
父/子关系 Join:为同一索引中的文档定义父/子关系
数组类型 字符型数组: ["one", "two"]
整型数组:[1, 2]
数组型数组:[1, [2, 3]] 等同于 [1, 2, 3]
对象数组:[{"name": "Mary", "age": 12}, {"name": "John", "age": 10}]

es不需要显示定义数组类型,只需要在插入数据时用[]表示即可。

# 3. 自动创建

如果没有手动设置MappingElasticsearch默认会自动解析出类型,且每个字段以第一次出现的为准。

curl -XPOST "http://elasticsearch:9200/test_mapping/_doc" -H 'Content-Type: application/json' -d'{  "name":"张三",  "age":18,  "height":1.75}'
1

ES 类型的自动识别是基于 JSON的格式,具体映射关系如下所示:

JSON类型 ElasticSearch类型
字符串 1.当匹配日期格式时,设置Date;如:2020-01-01 2.当设置数字时,设置float或者long; 3.当设置为Text时,自动增加keyword子字段
布尔值 boolean
浮点数 float
整数 long
对象 Object
数组 由第一个非空数值类型决定
空值 忽略

一旦Mapping字段对应的类型定下来之后,后续添加时必须要符合其类型,否则会报错。

# 4. 手动创建(推荐使用)

# 定义语法
{
  "settings":{
    //控制查询返回的最大结果数
   "index.max_result_window":20000 ,
    //segment段合并时可使用的最大线程数,为避免过度的io操作,该值一般不超过2
   "index.merge.scheduler.max_thread_count": 2 ,
    //分配到单个节点的最大分片数
   "index.routing.allocation.total_shards_per_node":10 ,
    //index刷新频率,频繁刷新会降低性能,一般设置为30s-60s;-1表示禁用刷新
   "index.refresh_interval":"-1" ,
    //translog刷新方式,如果对数据安全性要求不算太高,可设置为async以提升性能
   "index.translog.durability":"async" ,
    //translog刷新字节条件,超过1g才会刷新
   "index.translog.flush_threshold_size":"1024mb" ,
    //translog刷新时间条件,超过120s才会刷新
   "index.translog.sync_interval":"120s" ,
    //当有节点宕机后索引库多久触发副本balance操作
   "index.unassigned.node_left.delayed_timeout":"1d" ,
    //超过1s的查询会被记录到慢查询日志里
   "index.search.slowlog.threshold.query.info":"1s" ,
    //网络通信协议
   "index.store.type":"niofs" ,
    //index分片的副本数
   "index.number_of_replicas":0 ,
    //index分片数,需要注意的是es7.0默认索引分片数调整为1了
   "index.number_of_shards":8 ,
    //index数据的压缩方式,best_compression压缩可节省4-8倍的存储空间
   "index.codec":"best_compression" ,
    },
    "mappings":{
        "properties":{
            "字段名":{
                "type":"类型名",
              //指定分词器,ik_max_word、standard(默认)
                "analyzer":"ik_max_word",
              //该字段是否会被索引和可查询 默认true
                "index":true,
                //可以对一个字段提供多种索引模式,使用text类型做全文检索,也可使用keyword类型做聚合和排序
                "fields":{ 
                    "keyword":{
                        "type":"keyword",
                      //指定字段索引和存储的长度最大值,超过最大值的会被忽略
                        "ignore_above":3,
                    },
                }
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 示例
curl -XPUT "http://elasticsearch:9200/test_mapping" -H 'Content-Type: application/json' -d'{
    "settings":{
        "index.max_result_window":3,
        "index.routing.allocation.total_shards_per_node":2,
        "index.number_of_shards":2,
        "index.codec":"best_compression"
    },
    "mappings":{
        "properties":{
            "name":{
                "type":"keyword"
            },
            "address":{
                "type":"text",
                "fields":{
                    "keyword":{
                        "type":"keyword",
                        "ignore_above":10
                    }
                }
            },
            "phone":{
                "type":"text",
                "index":false
            },
            "age":{
                "type":"byte"
            },
            "score":{
                "type":"short"
            }
        }
    }
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 常用Mapping参数配置
参数名称 释义
analyzer 指定分析器,只有 text 类型字段支持。
copy_to 该参数允许将多个字段的值复制到组字段中,然后可以将其作为单个字段进行查询
dynamic 控制是否可以动态添加新字段,支持以下四个选项:true:(默认)允许动态映射false:忽略新字段。这些字段不会被索引或搜索,但仍会出现在_source返回的命中字段中。这些字段不会添加到映射中,必须显式添加新字段。runtime:新字段作为运行时字段添加到索引中,这些字段没有索引,是_source在查询时加载的。strict:如果检测到新字段,则会抛出异常并拒绝文档。必须将新字段显式添加到映射中。
doc_values 为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc值以节省磁盘空间(不支持 text 和 annotated_text)
eager_global_ordinals 用于聚合的字段上,优化聚合性能。
enabled 是否创建倒排索引,可以对字段操作,也可以对索引操作,如果不创建索引,任然可以检索并在_source元数据中展示,谨慎使用,该状态无法修改。
fielddata 查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中
fields 给 field 创建多字段,用于不同目的(全文检索或者聚合分析排序)
format 用于格式化代码,如"data":{ "type": "data", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" }
index 是否对创建对当前字段创建倒排索引,默认 true,如果不创建索引,该字段不会通过索引被搜索到,但是仍然会在 source 元数据中展示。
norms 是否禁用评分(在filter和聚合字段上应该禁用)
null_value 为 null 值设置默认值
search_analyzer 设置单独的查询时分析器

# 5. 查看映射

# 返回 aliases、mappings、settings
curl -XGET "http://elasticsearch:9200/test_mapping"
# 只查询别名
curl -XGET "http://elasticsearch:9200/test_mapping/_alias"
# 只查询mapping
curl -XGET "http://elasticsearch:9200/test_mapping/_mapping"
# 只查询settings
curl -XGET "http://elasticsearch:9200/test_mapping/_settings"
# 查询mapping中指定的几个字段(name,age)多个用逗号隔开
curl -XGET "http://elasticsearch:9200/test_mapping/_mapping/field/name,age"
1
2
3
4
5
6
7
8
9
10

# 6. 新增字段

curl -XPUT "http://elasticsearch:9200/test_mapping/_mappings" -H 'Content-Type: application/json' -d'{
    "properties":{
        "desc":{
            "type":"text"
        }
    }
}'

#返回
{"acknowledged":true}
1
2
3
4
5
6
7
8
9
10

# 7.删除映射

curl -XDELETE "http://elasticsearch:9200/test_mapping"
1

# 8.使用ReIndex重建索引

具体方法:

  • 如果要推倒现有的映射, 你得重新建立一个静态索引

  • 然后把之前索引里的数据导入到新的索引里

  • 删除原创建的索引

  • 为新索引起个别名, 为原索引名

通过这几个步骤可以实现了索引的平滑过渡,并且是零停机

# 1. 重新建立一个静态索引
PUT /user2
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "address": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

# 2. 把之前索引里的数据导入到新的索引里
POST _reindex
{
    "source": {
      "index": "user"
    },
    "dest": {
      "index": "user2"
    }
}

# 3. 删除原创建的索引
DELETE /user

# 4. 为新索引起个别名, 为原索引名
PUT /user2/_alias/user

GET /user
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34