映射mapping操作
Salted Fish 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. 自动创建
如果没有手动设置Mapping,Elasticsearch默认会自动解析出类型,且每个字段以第一次出现的为准。
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
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
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
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
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
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