dynamic用来配置处理新出现字段的行为,有true,false,strict 三种。
true 是默认值,会自动在 mapping 中添加字段,并在文档中保存新字段的值。
false 代表不会在 mapping 中添加字段,但会将数据存起来。
strict 代表既不会新增字段,也不会保存新字段的内容,遇到新字段直接报错。 另外,对于嵌套类型的字段,可以单独设置。
默认情况下,我们向索引中写入数据,如果有些字段之前未定义过,ES会自动猜测其类型,然后在mapping中生成。
举个例子:
PUT student
{
"mappings": {
"properties": {
"name": {
"type": "keyword",
"doc_values": false
}
}
},
"settings": {
"number_of_shards": "8",
"number_of_replicas": "2"
}
}
使用 bulk 插入数据:
POST _bulk
{ "index" : { "_index" : "student", "_id" : "1" } }
{ "name" : "张三", "age": 12 }
查询:
GET student/_search
# 查询结果
{
"took" : 18,
"timed_out" : false,
"_shards" : {
"total" : 8,
"successful" : 8,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "student",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 12
}
}
]
}
}
查询结果有 age。
查看 mapping:
GET student/_mapping
# 查询结果
{
"student" : {
"mappings" : {
"dynamic" : "true",
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "keyword",
"doc_values" : false
}
}
}
}
}
age 出现在了 mapping 中,且自动判断为 long 类型。
有时,自动判断的类型可能是不符合我们的预期的,但是呢,类型一旦确定,又是不能更改的。所以我们要谨慎对待这种特性。
dynamic 可以用来配置相关行为。
测试: dynamic 使用默认值 true 时
当我们没有配置 dynamic 时,用的默认值 true。也就是,下面两个方式效果是相同的:
方式1:
PUT student
{
"mappings": {
"properties": {
"name": {
"type": "keyword",
"doc_values": false
}
}
},
"settings": {
"number_of_shards": "8",
"number_of_replicas": "2"
}
}
方式2:
PUT student
{
"mappings": {
"dynamic": "true",
"properties": {
"name": {
"type": "keyword",
"doc_values": false
}
}
},
"settings": {
"number_of_shards": "8",
"number_of_replicas": "2"
}
}
测试: dynamic 为 false 时
PUT student
{
"mappings": {
"dynamic": "false",
"properties": {
"name": {
"type": "keyword",
"doc_values": false
}
}
},
"settings": {
"number_of_shards": "8",
"number_of_replicas": "2"
}
}
插入数据:
POST _bulk
{ "index" : { "_index" : "student", "_id" : "1" } }
{ "name" : "张三", "age": 12 }
查询:
GET student/_search
# 查询结果
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 8,
"successful" : 8,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "student",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 12
}
}
]
}
}
查看 mapping:
GET student/_mapping
# 查询结果
{
"student" : {
"mappings" : {
"dynamic" : "false",
"properties" : {
"name" : {
"type" : "keyword",
"doc_values" : false
}
}
}
}
}
age 没有出现在 mapping 中。
测试: dynamic 为 strict 时
PUT student
{
"mappings": {
"dynamic": "strict",
"properties": {
"name": {
"type": "keyword",
"doc_values": false
}
}
},
"settings": {
"number_of_shards": "8",
"number_of_replicas": "2"
}
}
插入数据:
POST _bulk
{ "index" : { "_index" : "student", "_id" : "1" } }
{ "name" : "张三", "age": 12 }
会报错:
{
"took" : 29,
"errors" : true,
"items" : [
{
"index" : {
"_index" : "student",
"_type" : "_doc",
"_id" : "1",
"status" : 400,
"error" : {
"type" : "strict_dynamic_mapping_exception",
"reason" : "mapping set to strict, dynamic introduction of [age] within [_doc] is not allowed"
}
}
}
]
}
查询:
GET student/_search
# 查询结果为空
查看 mapping:
GET student/_mapping
# 查询结果
{
"student" : {
"mappings" : {
"dynamic" : "strict",
"properties" : {
"name" : {
"type" : "keyword",
"doc_values" : false
}
}
}
}
}
单独设置嵌套类型字段
可参考 这篇文章.