使用ElasticSearch遇到的问题
在使用 ElasticSearch 的时候,如果索引中的字段是 text 类型,针对该字段聚合、排序和查询的时候常会出现 Fielddata is disabled on text fields by default. Set fielddata=true 的错误。本文总结这个错误出现的原因,可能的修复方法等。这个问题的解决方法并没有尝试过常见原因在 ElasticSearch 中,Fieldda
在使用 ElasticSearch 的时候,如果索引中的字段是 text 类型,针对该字段聚合、排序和查询的时候常会出现 Fielddata is disabled on text fields by default. Set fielddata=true 的错误。本文总结这个错误出现的原因,可能的修复方法等。
这个问题的解决方法并没有尝试过
常见原因
在 ElasticSearch 中,Fielddata 默认在 text 类型的字段时是不启用的。设想,如果默认打开,那么你的数据中,每个字符串大概率不一样的话,那么这个字段需要的集合大小(Cardinality)会非常大。
而这个字段是需要存在内存中的 (heap),因此不可能默认打开。所以如果你从一个 script 来对一个 text 字段进行排序、聚合或者查询的话,就会出现这个错误。
Fielddata is disabled on text fields by default. Set fielddata=true
on
[你的字段名字
] in order to load fielddata in memory by uninverting the
inverted index. Note that this can however use significant memory.
错误表现
出现这个错误的返回 JSON 会类似如下,root_cause 字段中的类型为 illegal_argument_exception。
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [YOUR_FIELD] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "XXXX",
"node": "YOUR_NODE",
"reason": {
"type": "illegal_argument_exception",
"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [YOUR_FIELD] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
}
}
]
},
"status": 400
}
多数情况下这个错误其实信息量相对大,且指导清晰了,无非查询的字段里没有 enable fielddata。但有时,如果你重新定义了 mapping ,则很有可能在查询时少了后缀的 .keyword (具体请见下文)
如何解决
- 尝试用 keyword 类型
尝试将对应的字段 map 成 keyword 类型。比如说:
PUT my-index-000001
{
"mappings": {
"properties": {
"my_field": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
但请注意,如果 map 过后,查询时的字段需要加上后缀 .keyword。比如如果你的字段如上是叫 my_field 那么查询时需要使用 my_field.keyword (参考: How to fix ElasticSearch ‘Fielddata is disabled on text fields by default’ for keyword field)
es.search(index="strings", body={
"size": 0,
"aggs" : {
"patterns" : {
"terms" : { "field" : "pattern.keyword" }
}
}
- 对已存在字段更改 mapping
如果这个字段已经存在的话,那么你需要把这个字段的 fielddata 改为 true。比如说,用以下 PUT 方法:
PUT my-index-000001/_mapping
{
"properties": {
"my_field": {
"type": "text",
"fielddata": true
}
}
}
- 重建索引
如果按方法 1 和 2 中的方式调整过后仍然有错误的话,建议重新建立索引。(参考How to fix ElasticSearch ‘Fielddata is disabled on text fields by default’ for keyword field)
总结
多数情况下,出现 Fielddata 相关的错误都是因为尝试聚合和排序一个 text 字段,因此只要把字段的 fielddata 设为 true 或者类型调整为 keyword 即可。如果是已存在字段可能需要重新索引。
index.highlight.max_analyzed_offset
错误表现
我在用python添加数据到es,在使用kibana查询的时候,查询全部是没有问题的,但是查询某个字段,例如 status时,就会报上面的错误,字面意思是该索引超过了最大偏移量
如何解决
-
百度上的解决方法几乎都是
调整该索引的最大偏移量
,有的文章也解释了调整之后的利弊,奈何才疏学浅,暂时理解不了。后来经过多次百度及询问同事,发现偏移量的意思,不准确的解释就是说这个字段的值太大了,以至于筛选的时候超过了最大限制,我的办法是把这个值的长度做一个限制,就解决了。
-
调整该索引的最大偏移量,看网上说不要调的太大,会影响内存,具体不是很明白
在kibana的Dev Tools中执行
PUT <your_index_name>/_settings
{
“index.highlight.max_analyzed_offset”: 1000000000
}
todo 在使用LogStash把mysql中的数据导入到es中,从ElasticSearch-head发现数据不一致了,但是查出来的结果是一致的
注意id
部分知识引用:https://kalasearch.cn/community/tutorials/elasticsearch-fielddata-is-disabled-on-text-fields-error/
更多推荐
所有评论(0)