fielddata
大多数字段默认情况下都会建立索引方便查询,但是针对排序,聚合以及脚本访问字段值则需要另外的访问方式;
查询操作需要回答’哪些doc包含查询的词’,而排序和聚合则需要回答’doc中该字段的值是多少’;
大多数字段可以通过文档索引在磁盘上默认设置的doc_values进行数据访问,但是text字段不支持doc_values;
text取而代之的是使用查询时内存数据结构–fielddata,该结构在将字段用于聚合、排序或脚本中时构建;其通过从磁盘中读取每个段的整个反向索引,然后反转分词与文档的关系并将结果存储在jvm堆内存当中;
fielddata在text字段中默认未启用
因为fielddata会消耗大量的堆内存,特别是当加载大量的text字段时;fielddata一旦加载到堆中,在segment的生命周期之内都将一致保持在堆中,另外加载fielddata也是一个比较耗时的过程,这可能会导致用户遇到延迟,故而默认情况下禁用fielddata参数;
若尝试针对text字段进行排序、聚合或脚本操作时,将会抛出以下异常:
PUT param_fielddata_index
{
"mappings": {
"properties": {
"field_data":{
"type": "text"
}
}
}
}
PUT param_fielddata_index/_doc/1
{
"field_data":"aaa"
}
PUT param_fielddata_index/_doc/2
{
"field_data":"bbb"
}
PUT param_fielddata_index/_doc/3
{
"field_data":"ccc"
}
GET param_fielddata_index/_search
{
"sort": [
{
"field_data": {
"order": "desc"
}
}
]
}
可能会出现的异常信息:
Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [field_data] in order to load field data by uninverting the inverted index. Note that this can use significant memory.
在考虑配置fielddata参数之前需要考虑这样做是否值得,在一般的text字段问题处理中是针对text字段额外映射一个keyword字段,使用keyword字段来进行排序、聚合和脚本操作;
PUT param_fielddata_index/_mapping
{
"properties":{
"field_data":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword"
}
}
}
}
}
若考虑再三确实需要配置fielddata,参考以下:
PUT param_fielddata_index
{
"mappings": {
"properties": {
"field_data":{
"type": "text",
"fielddata": true
}
}
}
}
fielddata过滤可减少加载到内存中的分词量,从而减少内存的使用;
频率过滤允许加载分词相关文档频率介于最小和最大值之间,数值可以使用精确值或者百分比表示,频率是按segment计算的,百分比是基于具有该字段值的文档数量,而不是segment中的所有文档;
通过使用min_segment_size指定该segment包含的最小文档数就可以排除掉小的segment:
PUT param_fielddata_index
{
"mappings": {
"properties": {
"field_data":{
"type": "text",
"fielddata": true,
"fielddata_frequency_filter": {
"min":0.001,
"max":0.1,
"min_segment_size":500
}
}
}
}
}
format
用于指定字段类型为date的格式化形式
ignore_above
用于指定类型(字符串或数组)长度超过参数指定大小时不会建立索引或存储,该参数可以通过api进行修改,修改后的只会对新增的生效,之前已生成的文档不会生效(除非进行更新);
//指定message字段为keyword类型且其ignore_above长度限制20个字符
PUT param_ignore_above_index
{
"mappings": {
"properties": {
"message":{
"type": "keyword",
"ignore_above": 20
}
}
}
}
//文档会建立索引,message字符少于20同样会建立索引
PUT /param_ignore_above_index/_doc/1
{
"message":"Syntax error"
}
//文档会建立索引,但是message字段不会建立索引
PUT param_ignore_above_index/_doc/2
{
"message":"Syntax error with some long stacktrace"
}
//可正常查询两条记录,但是聚合查询中只会有一条命中
GET param_ignore_above_index/_search
{
"aggs": {
"message": {
"terms": {
"field": "message",
"size": 10
}
}
}
}
ignore_malformed
默认情况下尝试将错误的数据类型索引到字段中会引发异常,整个文档也将无法建立索引; 若将ignore_malformed参数置为true,则可忽略类型不匹配造成的异常,不匹配的字段不会建立索引,其他的字段会被正常处理;
PUT param_ignore_malformed_index
{
"mappings": {
"properties": {
"age":{
"type": "integer",
"ignore_malformed": true
},
"level":{
"type": "integer"
}
}
}
}
//正常创建,age字段不会建立索引
PUT param_ignore_malformed_index/_doc/1
{
"text":"test ignore_malformed",
"age":"foo"
}
//创建异常
PUT param_ignore_malformed_index/_doc/2
{
"text":"test ignore_malformed",
"level":"foo"
}
//标记ignore_malformed的字段因为不建立索引,故而查询也是不被允许的
//异常信息:number_format_exception
GET param_ignore_malformed_index/_search
{
"query": {
"term": {
"age": {
"value": "foo"
}
}
}
}
ignore_malformed参数可以在以下类型字段上配置
类型 | 相关类型值 |
---|---|
numeric | long,integer,short,byte,double,float,half_float,scaled_float |
date | date,date_nanos |
geo | geo_point,geo_shape |
ip | IPv4,IPv6 |
索引级别的参数设置
可以在索引上设置index.mapping.ignore_malformed参数,在全局上忽略类型不匹配的字段,但是若在具体字段上设置了ignore_malformed参数,则会重载全局设置(以字段设置为准);
//全局配置ignore_malformed参数,若字段明确指定该参数则以字段上的配置为准
PUT param_global_ignore_malformed_index
{
"settings": {
"index.mapping.ignore_malformed":true
},
"mappings": {
"properties": {
"age":{
"type": "byte"
},
"level":{
"type": "integer",
"ignore_malformed": false
}
}
}
}
//查看字段映射
GET param_global_ignore_malformed_index/_mapping
//正常,age字段ignore_malform参数使用全局定义
PUT param_global_ignore_malformed_index/_doc/1
{
"text":"global ignore malformed param setting",
"age":"foo"
}
//报错,level字段ignore_malform参数取字段上定义
PUT param_global_ignore_malformed_index/_doc/2
{
"text":"global ignore malformed param setting",
"level":"foo"
}
不可使用ignore_malformed参数的类型:
1)、nested类型;
2)、object类型;
3)、range类型;
//报错,Mapping definition for [limit] has unsupported parameters: [ignore_malformed : true]
PUT param_ignore_malformed_limit_index
{
"mappings": {
"properties": {
"limit":{
"type": "object",
"ignore_malformed": true
}
}
}
}
index
index参数控制字段是否会建立索引,接受true/false值,默认为true,置为false情况下将无法进行查询
PUT param_index_set_index
{
"mappings": {
"properties": {
"limit":{
"type": "keyword",
"index": false
}
}
}
}
PUT /param_index_set_index/_doc/1
{
"limit":"index param test"
}
//报错,Cannot search on field [limit] since it is not indexed.
GET param_index_set_index/_search
{
"query": {
"term": {
"limit": {
"value": "index param test"
}
}
}
}
index_options
该参数用于控制将那些信息添加到倒排索引以进行搜索和高亮显示,index_options参数仅适用于text字段,应避免该参数与其他类型字段一起使用;
该参数只是以下参数:
类型 | 说明 |
---|---|
docs | 仅对文档编号建立索引,可以回答’这个词是否在这个字段当中存在’的问题 |
freqs | 对文档编号和分词频率建立索引,分词频率用于计算分词相关度分数(分词重复次数越多,其分数将越高) |
positions | 默认值,对文档编号、分词频率及分词位置建立索引,可用于短语查询 |
offsets | 对文档编号、分词频率、分词位置及分词起始位置(用于将分词字符串映射回原始字符串)建立索引,可用于加速高亮显示的查询 |
tips:词元位置与分词元始位置区别:文档在经过分词器切分之后产生多个词元,词元位置是相对其他词元而言的,而起始位置则是相对文档中所有词而言的;
//不支持phraseQuery
PUT param_index_options_index_1
{
"mappings": {
"properties": {
"text":{
"type": "text",
"index_options": "docs"
}
}
}
}
PUT param_index_options_index_1/_doc/1
{
"text":"hello world"
}
GET param_index_options_index_1/_search
{
"query": {
"match": {
"text": "hello world"
}
},
"highlight": {
"fields": {
"text": {}
}
}
}
PUT param_index_options_index_2
{
"mappings": {
"properties": {
"text":{
"type": "text",
"index_options": "freqs"
}
}
}
}
PUT param_index_options_index_2/_doc/1
{
"text":"hello world"
}
//报错,freqs不支持PhraseQuery,field:[text] was indexed without position data; cannot run PhraseQuery
GET param_index_options_index_2/_search
{
"query": {
"match_phrase": {
"text": "hello world"
}
}
}
GET param_index_options_index_2/_search
{
"query": {
"match": {
"text": "hello world"
}
}
}
PUT param_index_options_index_3
{
"mappings": {
"properties": {
"text":{
"type": "text",
"index_options": "positions"
}
}
}
}
PUT param_index_options_index_3/_doc/1
{
"text":"hello world"
}
GET param_index_options_index_3/_search
{
"query": {
"match": {
"text": "hello world"
}
},
"highlight": {
"fields": {
"text": {}
}
}
}
PUT param_index_options_index_4
{
"mappings": {
"properties": {
"text":{
"type": "text",
"index_options": "offsets"
}
}
}
}
PUT param_index_options_index_4/_doc/1
{
"text":"hello world"
}
GET param_index_options_index_4/_search
{
"query": {
"match": {
"text": "hello world"
}
},
"highlight": {
"fields": {
"text": {}
}
}
}
index_phrases
该参数可以将两个词元(term)组合成一个词组映射到单独字段中,接受true/false,默认为false,这可以使精确的短语查询更有效地运行(需要额外付出索引的代价);
另外这参数最好要在不删除停用词的情况下使用,因为包含停止词的短语将不会使用该组合字段并退而使用标准短语查询;
index_prefixes
index_prefixed参数可对词元进行前缀索引以提升词元前缀查询速度,可选以下参数:
类型 | 说明 |
---|---|
min_chars | 最小索引字符长度,必须大于0,默认为2(包含) |
max_chars | 最大索引字符长度,必须小于20,默认为5(包含) |
PUT param_index_prefix_index
{
"mappings": {
"properties": {
"text":{
"type": "text",
"index_prefixes":{
"min_chars":2,
"max_chars":10
}
}
}
}
}
PUT param_index_prefix_index/_doc/1
{
"text":"Once the RestClient has been created, requests can be sent by calling either performRequest or performRequestAsync"
}
PUT param_index_prefix_index/_doc/2
{
"text":"performRequest is synchronous and will block the calling thread and return the Response when the request is successful or throw an exception if it fails"
}
GET param_index_prefix_index/_search
{
"query": {
"prefix": {
"text": {
"value": "perform"
}
}
}
}
//报错,当prefix的字符长度低于min_chars报null_pointer_exception
GET param_index_prefix_index/_search
{
"query": {
"prefix": {
"text": {
"value": "p"
}
}
}
}
//当prefix的字符长度高于max_chars则无法查询出结果,返回结果为空
GET param_index_prefix_index/_search
{
"query": {
"prefix": {
"text": {
"value": "performRequest"
}
}
}
}