elasticsearch mappings之dynamic的三种状态

前言

一般的, mapping 可以分为  动态映射(dynamic mapping) 和 静态(显示) 映射 (explicit mapping) 和精准(严格) 映射(strict mapping)

具体由dynamic 属性控制

动态映射(dynamic: true)

创建一个索引

PUT m1
{
  "mappings": {
    "doc":{
      "properties": {
        "name": {
          "type": "text"
        },
        "age": {
          "type": "long"
        }
      }
    }
  }
}

 通过 GET m1/_mapping 看一下 mappings 信息:

{
  "m1" : {
    "mappings" : {
      "doc" : {
        "dynamic" : "true",
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "name" : {
            "type" : "text"
          }
        }
      }
    }
  }
}

添加一些数据,并且新增一个sex字段:

PUT m1/doc/1
{
  "name": "小黑",
  "age": 18,
  "sex": "不详"
}

此时看下 mappings

{
  "m1" : {
    "mappings" : {
      "doc" : {
        "dynamic" : "true",  # ES 默认允许添加新的字段  
        "properties" : {
          "age" : {
            "type" : "long"
          },
          "name" : {
            "type" : "text"
          },
          "sex" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      }
    }
  }
}

注意: mappings 一旦创建,则无法修改。因为Lucene 生成倒排索引后就不能改了

静态映射(dynamic:false)

现在,我们将 dynamic 值设置为 false

PUT m2
{
  "mappings": {
    "doc":{
      "dynamic":false,
      "properties": {
        "name": {
          "type": "text"
        },
        "age": {
          "type": "long"
        }
      }
    }
  }
}

现在测试一下false  和 true 有什么区别

PUT m2/doc/1
{
  "name": "小黑",
  "age":18
}
PUT m2/doc/2
{
  "name": "小白",
  "age": 16,
  "sex": "不详"
}

第二条数据相对于第一条数据,多了一个sex属性,我们可以用sex来做为条件查询一下:

GET m2/doc/_search
{
  "query": {
    "match": {
      "sex": "不详"
    }
  }
}

结果为空    为什么呢?

我们再此查一下mappings    结果在mappings中并没有 sex字段的映射关系。 

所以查不到。 但是存储时会存储该字段。  相当于能写 不能 查

严格模式(dynamic:strict)

同样 创建一个 mappings  

PUT m3
{
  "mappings": {
    "doc": {
      "dynamic": "strict", 
      "properties": {
        "name": {
          "type": "text"
        },
        "age": {
          "type": "long"
        }
      }
    }
  }
}

添加两篇文档

PUT m3/doc/1
{
  "name": "小黑",
  "age": 18
}
PUT m3/doc/2
{
  "name": "小白",
  "age": 18,
  "sex": "不详"
}

第一篇文档添加和查询都没问题。但是,当添加第二篇文档的时候,就报错了

也就是  连写都不能写

小结

  • 动态映射(dynamic:true):动态添加新的字段(或缺省)。
  • 静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现在查询中。
  • 严格模式(dynamic: strict):如果遇到新的字段,就抛出异常。

一般静态映射用的较多。就像HTMLimg标签一样,src为自带的属性,你可以在需要的时候添加id或者class属性。
当然,如果你非常非常了解你的数据,并且未来很长一段时间不会改变,strict不失为一个好选择。