在默认情况下,当索引一个文档时有字段是在映射中没有配置的,那么 Elasticsearch 将会根据该属性的类型,自动将其增加到映射中。
下面的POST请求会创建一个新的索引,并往里面插入一条文档:
POST /my-index/_doc
{
"tags": ["computer", "electronics"],
"in_stock": 4,
"created_at": "2022/01/01 00:01:02"
}
my-index
索引之前没有被创建过,尝试获取它的Mapping信息:
会发现:
created_at
字段会自动被解析成date
类型in_stock
传入的是json的整型,但被解析成了long
类型tags
同时被解析成了text和keyword两种类型,即上一章提到的multi-field mapping
下图是动态映射时JSON字段与Elasticsearch字段的对应关系:
动态映射的配置可以接受以下 3 种选择:
_source
中。这样可以避免创建索引,从而提高插入数据的性能。我们先来测试将映射设置为false
的效果。
创建people
索引,除了场景mapping的属性,同时设置dynamic=false
:
PUT /people
{
"mappings": {
"dynamic": false,
"properties": {
"first_name":{
"type": "text"
}
}
}
}
创建mapping完成后,往里面插入一条文档,这条文档除了first_name
字段外,还有额外的last_name
字段,此时依然可以插入成功:
获取mapping字义,由于dynamic mapping
被设置为false
,此时last_name
字段不再被自动mapping:
使用first_name来搜索,可以搜索到结果:
使用last_name搜索,不能搜索到结果
总结dynamic设置为false
后的效果:新字段不会增加到映射中,因此不能被搜索,但是内容依然会保存在_source
中。这样可以避免创建索引,从而提高插入数据的性能。
先将上一步创建的people
索引删除:
再重新创建索引,此时将dynamic
设置为strict
:
PUT /people
{
"mappings": {
"dynamic": "strict",
"properties": {
"first_name":{
"type": "text"
}
}
}
}
往里面插入文档,这条文档除了first_name
字段外,还有额外的last_name
字段。 此时发现直接报错:
所以,dynamic = strict
的效果是:索引文档时如果发现有新字段则报错,整个文档都不会被索引。这和关系型数据相似,在关系数据库中,如果插入表字义中不存在的字段,也会报错