目录
什么是Mapping?
Mapping类似于数据库中的schema定义,作用如下:
- 定义索引中的字段的名称
- 定义字段的数据类型,如字符串,数字,布尔等
- 字段,倒排索引的相关配置(是否分析,用那种分析器)
Mapping会把json文档映射程Lucene所需要的扁平格式
一个Mapping属于一个索引的type
- 每个文档都属于一个type
- 一个type由一个mapping定义
- 7.0开始,不需要在mapping中指定type信息
字段的数据类型
简单类型
- Text/Keyword
- Date
- Integer/Floating
- Boolean
- IPv4 & IPv6
复杂类型-对象和嵌套对象
特殊类型
- geo_point
- geo_shape
Dynamic Mapping
写入文档的时候,如果索引不存在,会自动创建索引
Dynamic Mapping的机制,使得我们无需手动定义Mappings,Elasticsearch会自动根据文档信息,推算出文档类型
推算有时候并不准确,比如我们将 false加上双引号,则会推算成text,而不是boolean
类型的自动识别
更改Mapping的字段类型
新增加字段
- Dynamic设为true时,一旦有新增字段的文档写入,Mapping也同时被更新
- Dynamic设为false时,Mapping不会被更新,新增字段的数据无法被索引,但是信息会出现在_source中
- Dynamic设为strict,文档写入失败
已有字段
- 一旦已经有数据写入,就不再支持修改字段定义
- luence实现的倒排索引,一旦生成后,就不允许修改
原因
- 如果修改了字段的数据类型,会导致已被索引的数据无法被搜索
- 但是如果是增加新的字段,就不会有这样的影响
实例
Dynamic为true
可以增加字段,新增字段的数据也可以被索引
Dynamic为false
Dynamic设为strict
发现无法写入
显式定义Mapping
自定义Mapping的一些建议
<1>可以参考API手册,纯手写
<2>为了减少输入的工作量,减少出错效率,可以依照一下步骤
- 创建一个临时的Index,写入一些样本数据
- 通过访问Mapping API 获得该临时文件的动态Mapping定义
- 修改后,使用该配置创建你的索引
- 删除临时索引
控制当前字段是否被索引
Index,控制当前字段是否被索引。默认为true,如果为false,则该字段不能被搜索
Index Options
null_value
需要对null值实现搜索
只有keyword类型支持Null_Value
copy_to
_all在7中被copy_to代替
满足一些特定的搜索需求
copy_to将字段的数值拷贝到目标字段,实现类似_all的作用
copy_to的目标字段不出现在_source中
数组类型
es不提供专门的数组类型,但是任何字段,都可以包含多个相同类型的数值
多字段特性
<1>实现精确匹配,增加一个keyword字段。keyword是不做任何处理,就把他当成一个单独的term输出
<2>使用不同的analyzer
- 为不同的索引提供不同的analyzer
- 拼音的搜索
Exact Values vs Full Text
Exact Values
包括具体的数字,日期,具体的字符串(App Store)
es中的keyword
不需要被分词
全文本,非结构化的文本数据
es中的text
自定义分词
当es自带的分词器无法满足时,可以自定义分词器,通过组合不同的组件(Character Filter,Tokenizer,Token Filter)实现
Character Filter
<1>在Tokenizer之前对文本进行处理,例如增加删除及替换字符,可以配置多个Character Filters,会影响Tokenizer position和offset信息
<2>一些自带的Character Filters
- html strip 去除html标签
- mapping 字符串替换
- pattern replace 正则匹配替换
Tokenizer
<1>将原始的文本按照一定的规则,且分为词(term or token)
<2>es内置的Tokenizers
- whitespace/standard/uax_url_email/keyword/path_hierarchy
<3>可以用java开发插件,实现自己的Tokenizer
Token Filters
<1>将Tokenizer输出的单词,进行增加,删除,修改
<2>自带的Token Filters
- lowcase/stop/synonmy(添加近义词)
网络爬虫抓取的数据,就可以用html_strip将标签剥离
实例
<1>html标签剥离,并实现精确匹配
<2>实现char_filter替换符号
<3>实现搜索任何一级的目录,都可以得到相应的结果
<4>移出stop words
<5>自定义分词器
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
#自定义分析器名称
"my_custom_analyzer":{
#类型,custom,自定义
"type":"custom",
#分词器,emotions,自定义,过滤表请
"char_filter":["emotions"],
#tokenizer自定义,过滤标点符号
"tokenizer":"punctuation",
#token filter 自定义english_stop,
"filter":[
"lowercase","english_stop"
]
}
},
"tokenizer": {
"punctuation":{
"type":"pattern",
"pattern":[".,!?"]
}
},
"char_filter": {
"emotions":{
"type":"mapping",
"mappings":["?=>happy"]
}
},
"filter": {
"english_stop":{
"type":"stop",
"stopwords":"english"
}
}
}
}
}
POST my_index/_analyze
{
"analyzer":"my_custom_analyzer",
"text":"i am very ? !?"
}
{
"tokens" : [
{
"token" : "i am very happy",
"start_offset" : 0,
"end_offset" : 12,
"type" : "word",
"position" : 0
}
]
}
mapping
character filter 映射字符过滤器
接收键和值的映射,每当遇到与键相同的字符串时,就用该键关联的值替换他们
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "keyword",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "mapping",
"mappings": [
"٠ => 0",
"١ => 1",
"٢ => 2",
"٣ => 3",
"٤ => 4",
"٥ => 5",
"٦ => 6",
"٧ => 7",
"٨ => 8",
"٩ => 9"
]
}
}
}
}
}