映射(mapping)
Mapping 是定义文档及其包含的字段是如何存储和索引的过程。
它的作用:
- 定义index下的字段名
- 定义字段类型,比如数值型、浮点型、布尔型等
- 定义倒排索引相关的设置,比如是否索引、记录position等
为了简单理解,可以把它理解为数据库中的表结构定义,比如说msql中定义一个表,然后每个字段的类型是什么,是整型,字符型,还是浮点型等等。mapping定义了每个字段的数据类型以及这些字段如何分词等相关属性,mapping是elasticsearch中很重要的一个部分。
如果把Elasticsearch比作关系型数据库的话,那么,映射就是建表,映射类型就是存储引擎,字段类型就是字段类型(还不是很了解的话,先继续往下看,最后会有例子,看完后就会很清楚了,之前的文章也有过说明)
首先请按顺序往下看,先了解一下内容:
为了能够将时间字段视为时间,数字字段视为数字,字符串字段视为全文或精确值字符串, Elasticsearch 需要知道每个文档中数据的类型。这个信息包含在映射中。
索引中每个文档都有 类型 。每种类型都有它自己的 映射。
核心简单类型:
Elasticsearch 支持 如下简单类型:
- 字符串: keyword,text
- 整数 : byte, short, integer, long
- 浮点数: float, double
- 布尔型: boolean
- 日期: date
当你索引一个文档--之前未曾出现-- Elasticsearch 会使用 动态映射(注意) ,通过JSON中基本数据类型,尝试猜测各种数据类型,使用如下规则:
Note: 这意味着如果你通过引号( "123" )索引一个数字,它会被映射为字符串类型,而不是 long 。但是,如果这个已经映射为 long ,那么 Elasticsearch 会尝试将这个字符串转化为 long ,如果无法转化,则抛出一个异常。
首先,我们向Elasticsearch中PUT(或POST)数据:
索引名:blog1, id:1
请注意PUT与POST的区别:
PUT 必须指定id, POST可以不指定id, es会自动帮我们生成:
出现created字样,表示PUT数据成功。
对比下面的POST,可以看出区别:
通过 /_mapping,我们可以查看 Elasticsearch 在一个或多个索引中的一个或多个类型的映射,Elasticsearch 根据我们索引的文档,(称为 属性 )动态生成映射。
GET /blog1/_mapping
其中的city字段以及country字段的type为text,显示正确,但是我们put的数据lat和lon,为数字,却显示为text(存储字符串),我的本意是要显示为地理位置经纬度坐标,所以在kibana中使用地图的时候,是不会正确显示的。
* 在es 2.*版本里存储字符串,只有string字段。
*5.*之后,把string字段设置为了过时字段,引入text,keyword字段
*这两个字段都可以存储字符串使用,但建立索引和搜索的时候是不太一样的
*keyword:存储数据时候,不会分词建立索引
*text:存储数据时候,会自动分词,并生成索引(这是很智能的,但在有些字段里面是没 用的,所以对于有些字段使用text则浪费了空间)
因此,像上面这种情况,当我们创建索引的时候,Elasticsearch会自动的为我们建立mapping(记录了各个字段的类型)也就是动态映射,但是它是会出错的,即有时候并不会按照我们的意图去生成相对应的字段类型。错误的映射会导致查询出现令人困惑的结果。
因此创建完成之后,一定要检查一下!而不是假设你的映射是正确的。
当 Elasticsearch 遇到文档中以前 未遇到的字段,它用 dynamic mapping(动态映射) 来确定字段的数据类型并自动把新的字段添加到类型映射
现在你知道什么是动态映射了吗?那出现上面错误的时候,我们该怎么办呢?别着急,接着往下看吧!
如需更详细的了解mapping,请查看文章:
自定义映射
尽管在很多情况下基本数据类型 已经够用,但你经常需要为单独域自定义映射 。自定义映射允许你执行下面的操作:
- 全文字符串域和精确值字符串域的区别
- 使用特定语言分析器
- 优化域以适应部分匹配
- 指定自定义数据格式
更新映射
当你首次 创建一个索引的时候,可以指定类型的映射。你也可以使用 /_mapping 为新类型(或者为存在的类型更新映射)增加映射。
mapping中的字段类型一旦设置,禁止直接修改,因为 lucene实现的倒排索引生成后不允许修改,可使用索引重建的方式。但是可以新增字段。
例如:增加一个birthday字段,类型为:date
索引重建的步骤如下:
1.使用正确的mapping新建索引和类型
例如要将lon及lat的类型改为: geo_point #用于地理位置经纬度坐标
创建新的索引: PUT /blog2
设置mapping:
2.使用reindex api将旧索引数据导入新索引
索引重建后可使用reindex命令迁移数据,如将blog1数据迁移至blog2,请求如下:
3.为新索引添加别名
为索引添加别名后,在程序代码中可以使用固定别名查询动态的索引名称,然后进行查询,如此索引重建则不会引起程序的变动
添加别名请求:
将旧索引别名迁移到新索引请求:
4.删除旧索引
添加或迁移别名后删除旧索引:
查看索引blog2:
使用_bulk插入多条数据:
查看插入的数据:
这样,字段的类型就更新完成了!!!