elasticsearch mappings之dynamic的三种状态
前言
一般的,mapping
则又可以分为动态映射(dynamic mapping)和静态(显示)映射(explicit mapping)和精确(严格)映射(strict mappings),具体由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": "不详"
}
当然,新的字段查询也没问题:
GET m1/doc/_search
{
"query": {
"match": {
"sex": "不详"
}
}
}
返回结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "m1",
"_type" : "doc",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"name" : "小黑",
"age" : 18,
"sex" : "不详"
}
}
]
}
}
现在,一切都很正常,跟elasticsearch自动创建时一样。那是因为,当 Elasticsearch 遇到文档中以前未遇到的字段,它用动态映射来确定字段的数据类型并自动把新的字段添加到类型映射。我们再来看mappings
你就明白了:
{
"m1" : {
"mappings" : {
"doc" : {
"dynamic" : "true",
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
},
"sex" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
}
通过上例可以发下,elasticsearch帮我们新增了一个sex
的映射。所以。这一切看起来如此自然。这一切的功劳都要归功于dynamic
属性。我们知道在关系型数据库中,字段创建后除非手动修改,则永远不会更改。但是,elasticsearch默认是允许添加新的字段的,也就是dynamic:true
。
其实创建索引的时候,是这样的:
PUT m1
{
"mappings": {
"doc":{
"dynamic":true,
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
}
}
}
}
}
上例中,当dynamic
设置为true
的时候,elasticsearch
就会帮我们动态的添加映射属性。也就是等于啥都没做!
这里有一点需要注意的是: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": "不详"
}
}
}
结果如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
结果是空的,也就是什么都没查询到,那是为什呢?来GET m2/_mapping
一下此时m2
的mappings
信息:
`{ "m2" : { "mappings" : { "doc" : { "dynamic" : "false", "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text" } } } } } }
可以看到elasticsearch并没有为新增的sex
建立映射关系。所以查询不到。
当elasticsearch察觉到有新增字段时,因为dynamic:false
的关系,会忽略该字段,但是仍会存储该字段。
在有些情况下,dynamic:false
依然不够,所以还需要更严谨的策略来进一步做限制。
严格模式(dynamic:strict)
让我们再创建一个mappings
,并且将dynamic
的状态改为strict
:
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": "不详"
}
第一篇文档添加和查询都没问题。但是,当添加第二篇文档的时候,你会发现报错了:
{
"error": {
"root_cause": [
{
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed"
}
],
"type": "strict_dynamic_mapping_exception",
"reason": "mapping set to strict, dynamic introduction of [sex] within [doc] is not allowed"
},
"status": 400
}
错误提示,严格动态映射异常!说人话就是,当dynamic:strict
的时候,elasticsearch如果遇到新字段,会抛出异常。
上述这种严谨的作风洒家称为——严格模式!
小结:
- 动态映射(dynamic:true):动态添加新的字段(或缺省)。
- 静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现在查询中。
- 严格模式(dynamic: strict):如果遇到新的字段,就抛出异常。
一般静态映射用的较多。就像HTML
的img
标签一样,src
为自带的属性,你可以在需要的时候添加id
或者class
属性。
当然,如果你非常非常了解你的数据,并且未来很长一段时间不会改变,strict
不失为一个好选择。
elasticsearch mappings之dynamic的三种状态的更多相关文章
- Hibernate 系列 07 - Hibernate中Java对象的三种状态
引导目录: Hibernate 系列教程 目录 1. Java对象的三种状态 当应用通过调用Hibernate API与框架发生交互时,需要从持久化的角度关注应用对象的生命周期. 持久化声明周期是Hi ...
- hibernate三种状态
转自:http://www.cnblogs.com/xiaoluo501395377/p/3380270.html 学过hibernate的人都可能都知道hibernate有三种状态,transien ...
- Hibernate的三种状态及对象生命周期
理解Hibernate的三种状态,更利于理解Hibernate的运行机制,这些可以让你在开发中对疑点问题的定位产生关键性的帮助. 三种状态 临时状态(Transient):在通过new关键字, ...
- hibernate学习笔记之三 持久化的三种状态
Hibernate持久化对象有3中状态,瞬时对象(transientObjects),持久化对象(persistentObjects),离线对象(detachedObjects) 下图显示持久化三种状 ...
- Hibernate中Java对象的三种状态
Hibernate中Java对象的三种 ...
- Hibernate延迟加载、三种状态、脏检查 缓存
一.持久化对象的唯一标识 java中按内存地址不同区分同一个类的不同对象,关系数据库用主键区分同一条记录,Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系 什么是OID? 解析: ...
- 【Java EE 学习 45】【Hibernate学习第二天】【对象的三种状态】【一对多关系的操作】
一.对象的三种状态. 1.对象有三种状态:持久化状态.临时状态.脱管状态(游离状态) 2.Session的特定方法能使得一个对象从一个状态转换到另外一个状态. 3.三种状态的说明 (1)临时状态:临时 ...
- hibernate对象的三种状态
对于hibernate,我想不在这里讲解了,我们就直接进入主题 在这里我将要说的是"hibernate对象的三种状态",对象是我们十分熟悉的,对吧!而对于对象它有三种状态 分别是瞬 ...
- Hibernate之对象的三种状态
Hibernate之Java对象的三种状态 一.简述 本博文大部分的思想和内容引子CSND上名为 FG2006 这位大神的文章,连接地址为:http://blog.csdn.net/fg2006/ar ...
随机推荐
- 封装ORM.py与mysql_client.py代码
ORM.py ''' ORM: 对象关系映射 ---> 映射到数据库MySQL中的数据表 类名 ---> 表名 对象 ---> 一条记录 对象.属性 ---> 字段 模拟Dja ...
- web性能优化-网络传输性能优化
浏览器工作原理:https://www.cnblogs.com/thonrt/p/10008220.html 浏览器渲染原理: https://www.cnblogs.com/thonrt/p/100 ...
- docker安装mysql5.6和redis3.2
环境:centos 6.8, docker version 1.7.1 1.docker安装mysql5.6 第一步:拉取镜像 docker pull mysql:5.6 第二步:docker run ...
- Vue组件使用
一.组件概念 有html模板,有css样式,有js逻辑的集合体 每一个组件都是一个vue实例 每个组件均具有自身的模板template,根组件的模板就是挂载点 每个组件模板只能拥有一个根标签 子组件的 ...
- windows下kafka配置入门 示例
实验平台与软件: 操作系统:windows7 32 位 java 开发包: jdk1.8.0_144 集群: zookeeper-3.3.6 消息队列: kafka_2.11-0.11.0.1 安装 ...
- Splay教程
目录 前言 引入 教程 Rotate Splay 一些其他操作: 区间翻转 结语 前言 Splay是名副其实的区间小能手.它会经常出现在一些有关区间的题上.而本蒟蒻只会Treap,感到分外难受,于是就 ...
- LOJ #6358 前夕 (组合计数、容斥原理)
题目链接 https://loj.ac/problem/6358 (另外一道\(4\)的倍数题左转loj #6356) 题意 题面写得就像一坨X一样,我来复述一下吧. 有\(N\)个元素构成的集合,要 ...
- 13.Python字符串详解(包含长字符串和原始字符串)
简单地理解,字符串就是“一串字符”,也就是用引号包裹的任何数据,比如“Hello,Charlie”是一个字符串,“12345”也是一个字符串. Python 要求,字符串必须使用引号括起来,可以使用单 ...
- css彩色(渐变)文字
css彩色文字也称渐变文字 在张鑫旭博客首页看到这效果,就自己研究了一下. 实现方法加个背景然后在根据文本剪切,再把文本填充为透明色让之前设置的背景颜色显示出来即可. -webkit-backgrou ...
- 笔记本电脑如何同时上内外网(通过usb外接网卡实现虚拟机连外网)
我们这里达成的方式不是内外网切换,而是真正意义上的同时上内网和外网 原理: 通过构建虚拟机,利用usb外接网卡(某宝某东都有售,价格在50大洋左右)使虚机连接外网,然后开启虚拟机的unity模式 准备 ...