# 定制化自己的 dynamic mapping 策略
# 定制 dynamic 策略
有如下三种可选
- true:遇到陌生字段,就进行 dynamic mapping
- false:遇到陌生字段,就忽略
- strict:遇到陌生字段,就报错
示例,创建一个策略
- 对于 my_type 全局设置策略为 遇到陌生字段就报错
- 对于 my_type.address 字段 策略设置为自动 mapping
PUT /my_index { "mappings": { "my_type": { "dynamic": "strict", "properties": { "title": { "type": "text" }, "address": { "type": "object", "dynamic": "true" } } } } }
测试全局策略是否生效
PUT /my_index/my_type/1
{
"title": "my article",
"content": "this is my article",
"address": {
"province": "guangdong",
"city": "guangzhou"
}
}
2
3
4
5
6
7
8
9
响应错误,content 字段校验未通过
{
"error": {
"root_cause": [
{
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [content] within [my_type] is not allowed"
}
],
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [content] within [my_type] is not allowed"
},
"status": 400
}
2
3
4
5
6
7
8
9
10
11
12
13
测试 address 测自动 mapping 策略
PUT /my_index/my_type/1
{
"title": "my article",
"address": {
"province": "guangdong",
"city": "guangzhou"
}
}
2
3
4
5
6
7
8
响应成功
{
"_index": "my_index",
"_type": "my_type",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}
2
3
4
5
6
7
8
9
10
11
12
13
# 查看 mapping 信息
GET /my_index/_mapping/my_type
------------------------------- 响应
{
"my_index": {
"mappings": {
"my_type": {
"dynamic": "strict",
"properties": {
"address": {
"dynamic": "true",
"properties": {
"city": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"province": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"title": {
"type": "text"
}
}
}
}
}
}
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
可以看到 address 下被自动 mapping 了两个字段的配置
# 定制 dynamic mapping 策略
自动 mapping 的相关信息
# date_detection
默认会按照一定格式识别 date,比如 yyyy-MM-dd 。
但是如果某个 field 先过来一个 2017-01-01 的值,就会被自动 dynamic mapping 成 date, 后面如果再来一个 "hello world" 之类的值,就会报错。
可以手动关闭某个 type 的 date_detection,如果有需要,自己手动指定某个 field 为 date 类型。
PUT /my_index/_mapping/my_type
{
"date_detection": false
}
2
3
4
# 定制自己的 dynamic mapping template(type level)
TIP
type level:就是在哪一个级别/层面。比如在 index 层面配置,那么就对所有的 type 生效
动态 mapping 模板:就是当某一个字段匹配到模板中的通配符配置时就应用该配置的 mapping 配置
配置一个动态模板
- 为 my_type 配置动态模板
- en:为该配置取一个名称
- match:通配符匹配字段;
- match_mapping_type:字段 type 也要匹配上
- mapping:mapping 的信息配置
下面的配置意思是:当一个 string 字段名称后缀为 _en
结尾时就使用此 mapping
PUT /my_index
{
"mappings": {
"my_type": {
"dynamic_templates": [
{ "en": {
"match": "*_en",
"match_mapping_type": "string",
"mapping": {
"type": "string",
"analyzer": "english"
}
}}
]
}}}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
测试一个不匹配的数据
先查询当前的 mapping
GET /my_index/_mapping/my_type/
-------------------- 响应
{
"my_index": {
"mappings": {
"my_type": {
"dynamic_templates": [
{
"en": {
"match": "*_en",
"match_mapping_type": "string",
"mapping": {
"analyzer": "english",
"type": "string"
}
}
}
]
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
再插入数据
PUT /my_index/my_type/1
{
"title": "this is my first article"
}
2
3
4
再次查询当前的 mapping,title 字段没有匹配到动态模板配置
GET /my_index/_mapping/my_type/
-------------------- 响应
{
"my_index": {
"mappings": {
"my_type": {
"dynamic_templates": [
{
"en": {
"match": "*_en",
"match_mapping_type": "string",
"mapping": {
"analyzer": "english",
"type": "string"
}
}
}
],
"properties": {
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
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
插入一条匹配的数据
PUT /my_index/my_type/2
{
"title_en": "this is my first article"
}
2
3
4
查看 mapping ,可以看到被匹配上了
GET /my_index/_mapping/my_type/
-------------------- 响应
{
"my_index": {
"mappings": {
"my_type": {
"dynamic_templates": [
{
"en": {
"match": "*_en",
"match_mapping_type": "string",
"mapping": {
"analyzer": "english",
"type": "string"
}
}
}
],
"properties": {
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"title_en": {
"type": "text",
"analyzer": "english"
}
}
}
}
}
}
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
搜索再次测试是否能搜索到结果
GET /my_index/my_type/_search?q=title:is
------------------- 响应
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.2824934,
"hits": [
{
"_index": "my_index",
"_type": "my_type",
"_id": "1",
"_score": 0.2824934,
"_source": {
"title": "this is my first article"
}
}
]
}
}
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
GET /my_index/my_type/_search?q=title_en:is
----------------------- 响应
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
title 没有匹配到任何的 dynamic 模板,默认就是 standard 分词器,不会过滤停用词,is 会进入倒排索引,用 is 来搜索是可以搜索到的
title_en 匹配到了 dynamic 模板,就是 english 分词器,会过滤停用词,is 这种停用词就会被过滤掉,用 is 来搜索就搜索不到了
# 定制自己的 default mapping template(index level)
- 在 index 这个层面全局关闭
_all
功能 - 在 blog 这个 type 下打开
_all
功能
PUT /my_index
{
"mappings": {
"_default_": {
"_all": { "enabled": false }
},
"blog": {
"_all": { "enabled": true }
}
}
}
2
3
4
5
6
7
8
9
10
11