前言
在使用ElasticSearch(后文均称为ES)的过程中,由于中文官方文档不足和网上资源较少,本着服务自己和造福后人的目的,详细了部分官方文档的描述,就有了这系列使用教程。系列材料源于官方文档并辅以一定额外实例,并感谢翻译中文文档的作者们。本系列以ES 5.6.0 为标准版本,如果版本不同引起的歧义,请参考官方文档。
正文
映射解释
无论是mapping还是映射从字面上看,都知道是产生的数据文档存储到ES内部文档的一种对应关系。这种对应关系决定了文档存储数据的准确性。只有知道了文档中每个域数据的实际存储含义,才能完成正确的存储和搜索。正如同为一个字符串,映射为全文文本(text)和关键字(keyword)有截然不同的含义。全文文本可以在分词后,被搜索查询,而关键字的功能更偏向于数据精准匹配和聚合分析。
而映射就是针对一种索引下的类型定义,同时映射的域的类型有多种:
域数据类型:
- 简单数据类型如
text
,keyword
,date
,long
,double
,boolean
orip
.(不再有string类型) - 复杂对象类型如
object
ornested
. - 特殊的数据类型如
geo_point
,geo_shape
, orcompletion
.
注意事项
映射下的数据域太多
如果数据域太多很可能导致OOM,而这种情况也是很容易发生。当文档不停的添加新的数据域,而动态映射也同样会不停的添加数据域类型。
映射总数据域限制
:1000映射深度限制
: 内置对象的层数 默认20相同索引下不同类型的相同字段共享映射
虽然类比索引为SQL的数据库,类型为表,但是不同在于相同索引下不同类型是相关的。即同一个
Index
下,有type1
和type2
两种类型。两种类型包含同一个字段field
。而这个字段field
的映射类型只有一种。如果先在type1
设置为text,不能同时在type2
设置为long。虽然同索引下不同类型的相同字段关联会导致一些问题,但是5.6.0的版本就是这样的。而过后版本有移除类型type
的计划:Removal of mapping types!
使用映射
动态映射
当将数据填入索引类型中,无需设置数据域和映射。这都是归功于动态映射。ES会自动识别填入的数据,无论是简单数据类型还是对象数据类型。
动态映射 规则同样可以通过设置实现不同的效果。
而动态映射的缺点在于自动识别的数据域类型并不能百分百符合需求。如果目标类型是text
,却第一次存了‘2017/12/29’,映射自动识别为date
类型。此后所有插入均失败。因此便有了定制映射:
定制映射
通过预先定义index
type
的映射,以适配数据域的插入,实际操作过程下文会介绍。
修改映射
不同于保存的文档可以随意修改,预设好的索引映射是不能修改的。修改了已存在的数据域映射意味着对已存在的文档数据含义的否定。因此,你应该重新创建一个新的索引然后将数据转移到新的索引中,而不是直接更改数据映射。
映射实例
PUT /{{host}}:{{port}}/demo
{
"mappings": {
"doc": {
"properties": {
"title": { "type": "text" },
"name": { "type": "text" },
"age": { "type": "integer" },
"content": {
"type":"text",
"index":"analyzed",
"analyzer":"ik_max_word" },
"key":{
"type":"keyword",
"index":"not_analyzed" },
"created": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis" }
}
}
}
}
创建demo索引下类型为doc的映射。数据域content采用ik中文分词,key采用关键字,不分词。
note:
- 5.6.0版本中,
field
中的index
还是analyzed和not_analyzed。在6.0版本改为true和false。但是含义都是分词和不分词