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 ...
随机推荐
- idea 注册码 2月
https://blog.csdn.net/zhw0596/article/details/81394870 不显示.java后缀 https://segmentfault.com/q/1010000 ...
- solr创建core
创建Core的两种方法: 第一种方法: 1.打开dos命令窗口,切换目录到${solr.home}\bin,然后输入:solr create -c corename之后回车: 2.打开solr安装文件 ...
- ffmpeg函数03__av_seek_frame()
当需要把视频跳转到N秒的时候可以使用下面的方法:int64_t timestamp = N * AV_TIME_BASE; av_seek_frame(fmtctx, index_of_video, ...
- CI/CD----jenkins安装配置
1.下载jenkins rpm包. https://pkg.jenkins.io/redhat/ 2.安装 rpm -ivh jenkins-2.182-1.1.noarch systemctl st ...
- GoAccess安装及分析nginx实时日志
GoAccess是一个基于终端的快速日志分析器.其核心思想是实时快速分析和查看Web服务器统计信息,而无需使用您的浏览器(如果您希望通过SSH快速分析访问日志,或者只是喜欢在终端中工作),终端输出是默 ...
- json dumps dump区别
.json.dumps()和json.loads()是json格式处理函数(可以这么理解,json是字符串) (1)json.dumps()函数是将一个Python数据类型列表进行json格式的编码( ...
- 解决Jenkins忘记用户名,密码
windows系统: 进入windows默认目录 C:\Users\Administrator\.jenkins\users 修改配置文件即可
- python+openCV实现双目视差图及测距
通过matlab标定得到相机参数放到stereoconfig.py import numpy as np import cv2 #双目相机参数 class stereoCameral(object): ...
- noi.ac NA529 【神树的矩阵】
表示今天一发A了这题拿了rk3...是个sb构造... 考虑除了\(n=1/m=1\)的情况,最小次数\(ans\)不会\(>3\). 对于\(n=1/m=1\),暴力即可. 然后考虑\(ans ...
- 手机端自适应缩放显示 js
<script> var _width = parseInt(window.screen.width); var scale = _width/640; var ua = navigato ...