Elasticsearch-34-定制自己的dynamic mapping策略

定制dynamic策略

true: 遇到陌生字段,就进行dynamic mapping
false: 遇到陌生字段,就忽略
strict: 遇到陌生字段,就报错

示例

我们现在来新建一个index.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PUT /my_index
{
"mappings": {
"my_type": {
"dynamic":"strict", // 1
"properties": {
"title":{
"type": "text"
},
"address":{
"type": "object",
"dynamic":"true" // 2
}
}
}
}
}

1处,我们设置了这个my_type的dynamic是strict,就是遇到陌生的字段,就报错
2处,设置了address这个object类型的filed的dynamic是true, 遇到陌生字段就进行dynamic mapping

先来放一条数据进去

1
2
3
4
5
6
7
8
9
PUT /my_index/my_type/1
{
"title":"my title",
"content":"test content", // 1
"address":{
"province":"zhejiang", // 2
"city":"hangzhou" // 3
}
}

1处,content这个field 我们创建索引时,并没有设置设置这个content, dynamic是strict,遇到陌生字段应该报错
2,3处的province和city,我们也没有设置, address的dynamic策略应该是遇到陌生字段就进行dynamic mapping

运行上面代码,返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"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
}

报错了因为我们在my_type中设置的dynamic是strict

然后把content这个field删掉

1
2
3
4
5
6
7
8
PUT /my_index/my_type/1
{
"title":"my title",
"address":{
"province":"zhejiang",
"city":"hangzhou"
}
}

执行后,添加成功. 然后我们来查询一下这个type的mapping

1
GET /my_index/_mapping/my_type

返回值:

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
{
"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"
}
}
}
}
}
}

可以看到address中的province和city这两个字段已经被自动dynamic mapping了

定制dynamic mapping策略

date_detection

es会默认按照一定的格式识别date类型,比如yyyy-MM-dd,但是如果某个field先过来一个2018-01-01的值,就会被自动dynamic mapping 成 date类型,后面如果再来一个”hello word”之类的值,就会报错.
我们可以手动关闭某个type的date_detection,如果有需要,自己手动指定某个field为date类型.

1
2
3
4
PUT /index/_mapping/type
{
"date_detection": false
}

定制自己的dynamic mapping template (type级别)

首先我们需要在建索引的时候添加一个模板.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PUT /my_index
{
"mappings": {
"my_type": { // type名称
"dynamic_templates":[
{
"en":{ // 模板名称,自定义的
"match":"*_en", // 通配符匹配_en结尾的field
"match_mapping_type":"string",
"mapping":{
"type":"string",
"analyzer":"english" // english分词器
}
}
}
]
}
}
}

上面这段代码就是说 field名称是_en结尾的话,就是string类型的,分词器是english分词器

我们来添加两条数据,然后查询测试一下

1
2
3
4
5
6
7
8
9
PUT /my_index/my_type/1
{
"title": "this is my first article"
}

PUT /my_index/my_type/2
{
"title_en": "this is my first article"
}

分别用title 和 title_en去匹配 is这个词.会发现 用title_en是匹配不到的

title没有匹配到任何的dynamic模板,默认就是standard分词器,不会过滤停用词,is会进入倒排索引,用is来搜索是可以搜索到的
title_en匹配到了dynamic模板,就是english分词器,会过滤停用词,is这种停用词就会被过滤掉,用is来搜索就搜索不到了

定制自己的dynamic mapping template (index级别)

例:

1
2
3
4
5
6
7
8
9
10
11
PUT /my_index
{
"mappings": {
"_default_": {
"_all": { "enabled": false }
},
"blog": {
"_all": { "enabled": true }
}
}
}

就是说默认的type的_all是禁用的, blog这个type的_all是启用的.