Elasticsearch实战——mapping
Elasticsearch提供了足够多的映射参数对字段的映射进行参数设置,实现一些常用的功能,比如字段的分词器、日期格式、检索模型的选择等都是通过参数配置来完成的,下面一一介绍各个参数的用法。
1. analyzer
analyzer
参数用于指定文本字段的分词器,对索引和查询都有效。分词器会把文本类型的内容转换为若干个词项,查询时分词器同样会把查询字符串通过和索引时相同的分词器或其他分词器进行解析。以常用的IK
中文分词器为例,对于title
字段,analyzer
参数的取值为ik_max_word
,意味着title
字段内容索引时和查询时都使用ik_max_word
分词,映射配置如下:
PUT website
{
"mappings":{
"properties":{
"title":{
"type":"text",
"analyzer":"ik_max_word"
}
}
}
}
analyzer
该参数可以在查询、字段、索引级别中指定,其优先级如下(越靠前越优先):
- 字段上定义的分词器
- 索引配置中定义的分词器
- 默认分词器(
standard
)
在查询上下文,分词器的查找优先为:
full-text query
中定义的分词器- 定义类型映射时字段中
search_analyzer
定义的分词器 - 定义字段类型映射时
analyzer
定义的分词器 - 索引中
default_search
中定义的分词器 - 索引中默认定义的分词器
- 标准分词器(
standard
)
2. search_analyzer
大多数情况下索引和搜索的时候应该指定相同的分词器,确保query解析以后的索引中的词项一致。但是有时候也需要指定不同的分词器。例如,使用edge_ngram
过滤器实现自动补全。默认情况下查询会使用analyzer
属性指定的分词器,但也可以被search_analyzer
覆盖。
示例如下:
PUT website
{
"settings":{
"analysis":{
"filter":{
"autocomplete_filter":{
"type":"edge_ngram",
"min_gram":1,
"max_gram":20
}
},
"analyzer":{
"autocomplete":{
"type":"custom",
"tokenizer":"standard",
"filter":[
"lowercase",
"autocomplete_filter"
]
}
}
}
},
"mappings":{
"properties":{
"title":{
"type":"text",
"analyzer":"autocomplete",
"search_analyzer":"standard"
}
}
}
}
title
字段使用autocomplete
分词器进行分词,但是使用standard
分词器进行搜索。索引一条文档:
PUT website/1
{
"title":"Quick Brown Fox"
}
title
字段生成的倒排索引包含以下词项:
[q, qu, qui, quic, quick, b, br, bro, brow, brown, f, fo, fox]
3. normalizer
normalizer
参数用于解析前的标准化配置,注意针对keyword
类型,比如把所有字符转化为小写。下面的例子中foo
字段的值在解析前使用自定义的normalizer
把字符串标准化并转化为小写的形式:
PUT website
{
"settings":{
"analysis":{
"normalizer":{
"my_normalizer":{
"type":"custom",
"char_filter":[],
"filter":["lowercase", "asciifolding"]
}
}
}
},
"mappings":{
"properties":{
"foo":{
"type":"keyword",
"normalizer":"my_normalizer"
}
}
}
}
4. boost
boost
字段用于设置字段的权重。比如设置关键字出现在title
字段的权重是出现在content
字段中权重的两倍,其中content
字段的权重默认是1,mapping
如下:
PUT website
{
"mappings":{
"properties":{
"title":{
"type":"text",
"boost":2
},
"content":{
"type":"text"
}
}
}
}
也可以在查询时设置权重:
POST website/_search
{
"query":{
"match":{
"title":{
"query":"我是中国人",
"boost":2
}
}
}
}
推荐在查询
的时候指定boost
。在索引时设置权重,如果不重建索引,权重无法修改。在查询时指定权重可以达到同样的效果,修改权重更加灵活。
5. coerce
coerce
属性用于清除脏数据,默认值是true
。整型数字5
有可能被写成字符串"5"
或者浮点数5.0
。coerce
属性可以用来清除脏数据,字符串和浮点数会被强制转换为整数。
6. copy_to
copy_to
参数由于自定义_all
字段,可以把多个字段的值复制到一个超级字段。下面的例子中把title
和content
字段的内容合并到full_content
。
PUT website
{
"mappings":{
"properties":{
"title":{
"type":"text",
"copy_to":"full_content"
},
"content":{
"type":"text",
"copy_to":"full_content"
},
"full_content":{
"type":"text"
}
}
}
}
7. doc_values
doc_values
参数是为了加快排序、聚合操作。在建立倒排索引的时候,额外增加一个**列式存储映射
**,是一种空间换时间的做法。默认是开启的,对于不需要聚合或排序的字段可以关闭doc_values
节省空间。
PUT website
{
"mappings":{
"properties":{
"status":{
"type":"keyword"
},
"session_id":{
"type":"keyword",
"doc_values":false
}
}
}
}
注意:text
类型不支持doc_values
8. dynamic
在mapping
中可以通过dynamic
设置是否自动新增字段,接受以下参数:
true
:默认值,自动添加字段false
:忽略新字段strict
:严格模式,发现新字段抛出异常
使用方法:
PUT website
{
"mappings":{
"dynamic":"strict",
"properties":{
"title":{
"type":"text"
}
}
}
}
9. enabled
ES
默认会索引所有的字段,而有些字段只需要存储,没有查询或者聚合的需求,这种情况下就可以使用enabled参数来控制。enabled
设置为false
的字段,ES
会跳过字段内容,该字段的值只能从 _source
中获取,但是不可以被搜索,字段可以是任意类型。例如:
PUT website
{
"mappings":{
"properties":{
"name":{
"enabled":false
}
}
}
}
10. fielddata
text类型的字段的聚合可以开启fielddata
。fielddata
在字段首次聚合、排序或者使用脚本的时候生成。ES
通过读取磁盘上的倒排记录表重新生成文档词项关系,最后再Java堆内存
中排序。
text
字段的fielddata
属性默认是关闭的,开启fielddata
非常消耗内存。
给text
类型的字段开启fielddata
的命令如下:
PUT website
{
"mappings":{
"properties":{
"title":{
"type":"text",
"fielddata":true
}
}
}
}
11. format
ES中,使用format
参数指定日期格式。
PUT website
{
"mappings":{
"properties":{
"indexAt":{
"type":"date",
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
12. ignore_above
指定字符串最大长度,超过最大长度会被忽略,只用于keyword
类型,示例如下:
PUT website
{
mappings:{
"properties":{
"message":{
"type":"keyword",
"ignore_above":20
}
}
}
}
13. ignore_malformed
ignore_malformed
可以忽略不规则数据。给一个字段索引不合适的数据类型会发生异常,从而导致整个文档索引失败。如果ignore_malformed
参数设置为true,异常会被忽略,出现异常的字段不会被索引,其他字段正常索引。
14. index
index
属性指定字段是否索引,不索引也就不可以搜索,取值为true
或false
。
15. index_options
index_options
参数控制索引时存储哪些信息到倒排索引中。设置title
字段存储文档编号、词频、词的位置、词项开始和结束的字符位置,映射如下:
PUT website
{
"mappings":{
"properties":{
"title":{
"type":"text",
"index_options":"offsets"
}
}
}
}
index_options
参数取值表:
参数 | 作用 |
---|---|
docs | 只存储文档编号,默认取值 |
freqs | 存储文档编号和词项频率 |
positions | 存储文档编号、词项频率、词项偏移位置,偏移位置可用于临近搜索和短语查询 |
offsets | 文档编号、词项频率、词项的位置、词项开始和结束的字符位置都被存储,offset 设为true 会使用Postings highlighter |
16. fields
fields
参数可以让同一个字段有多种不同的索引方式。比如一个文本类型的字段,可以使用中文全文检索,使用拼音检索,映射如下:
PUT website
{
"mappings":{
"properties":{
"title":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart",
"fields":{
"pinyin":{
"type":"text",
"analyzer":"pinyin"
}
}
}
}
}
}
17. norms
norms
参数用于标准化文档,以便查询时计算文档的相关性。norms
虽然对评分有用,但是会消耗较多的磁盘空间,如果不需要对某个字段进行评分,最好不要开启norms
。
18. null_value
值为null
的字段不索引也不可以搜索,null_value
参数可以让值为null
的字段显示的可索引、可搜索
。示例如下:
PUT website
{
"mappings":{
"properties":{
"status":{
"type":"keyword",
"null_value":"NULL"
}
}
}
}
PUT website/1
{
"status":null
}
PUT website/2
{
"status":[]
}
GET website/_search
{
"query":{
"term":{
"status":"NULL"
}
}
}
文档1
可以被搜索到,因为status
的值为null
,文档2
不可以被搜索到,因为status
的值为空数组
,但不是null
。
19. properties
类型的映射、普通字段、objet类型
和nested类型
的字段都称为properties(属性),这些属性可以为任意的数据类型,包括object
和nested
类型,属性可以通过以下方式加入:
- 在创建索引时明确的定义它们。
- 在使用PUT mapping API 添加或更新映射类型时明确定义它们。
- 索引包含新字段的文档时动态地加入。
20. similarity
similarity参数用于指定文档评分模型,参数有三个:
BM25
:ES
和Lucene
默认的评分模型。classic
:TF/IDF
评分模型。boolean
:布尔评分模型。
PUT website
{
"mappings":{
"properties":{
"name":{
"type":"text",
"similarity":"classic"
}
}
}
}
21. store
默认情况下,字段是被索引的,也可以搜索,但是不存储。因为_source
字段里保存了一份原始文档。在某些情况下还是有意义的,比如不存储原始文件,只存储需要的几个字段。
PUT website
{
"mappings":{
"_source":{
"enabled":false
},
"properties":{
"title":{
"type":"text",
"store":true
},
"indexAt":{
"type":"date",
"store":true
},
"content":{
"type":"text"
}
}
}
}
22. term_vector
词向量包含文本被解析后的以下信息:
- 词项集合
- 词项位置
- 词项的起始字符映射到原始文档中的位置
term_vector
参数的取值表:
参数取值 | 含义 |
---|---|
no | 默认值,不存储词向量 |
yes | 只存储词项集合 |
with_positions | 存储词项和词项位置 |
with_offsets | 词项和字符偏移量 |
with_positions_offsets | 存储词项、词项位置、字符偏移位置 |
23. 关注我
搜索微信公众号:java架构强者之路