Fielddata is disabled on text fields by default. Set fielddata=true on [user] in order to load field

本文介绍了解决Elasticsearch中因默认禁用text字段的fielddata而导致的聚合查询失败问题。通过设置特定text字段的fielddata为true,可以成功启用内存中的fielddata缓存,进而实现聚合操作。

Fielddata is disabled on text fields by default. Set fielddata=true on [gender] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memor

ES进行如下聚合操作时,会报如题所示错误:

复制代码
 1 ➜  Downloads curl -XPOST 'localhost:9200/bank/_search?pretty' -d '
 2         {
 3           "size": 0,
 4           "aggs": {
 5             "group_by_state": {
 6               "terms": {
 7                 "field": "state"
 8               }
 9             }
10           }
11         }'
复制代码

提示报错如下:

复制代码
 1 {
 2   "error" : {
 3     "root_cause" : [
 4       {
 5         "type" : "illegal_argument_exception",
 6         "reason" : "Fielddata is disabled on text fields by default. Set fielddata=true on [state] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory."
 7       }
 8     ],
 9     "type" : "search_phase_execution_exception",
10     "reason" : "all shards failed",
11     "phase" : "query",
12     "grouped" : true,
13     "failed_shards" : [
14       {
15         "shard" : 0,
16         "index" : "bank",
17         "node" : "nkL8C69pTMuXrZBXicjshw",
18         "reason" : {
19           "type" : "illegal_argument_exception",
20           "reason" : "Fielddata is disabled on text fields by default. Set fielddata=true on [state] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory."
21         }
22       }
23     ],
24     "caused_by" : {
25       "type" : "illegal_argument_exception",
26       "reason" : "Fielddata is disabled on text fields by default. Set fielddata=true on [state] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory."
27     }
28   },
29   "status" : 400
30 }
复制代码

  根据官方文档显示,出现该错误是因为5.x之后,Elasticsearch对排序、聚合所依据的字段用单独的数据结构(fielddata)缓存到内存里了,但是在text字段上默认是禁用的,如果有需要单独开启,这样做的目的是为了节省内存空间。——官方文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html

开启方法:

复制代码
1 ➜  Downloads curl -XPUT 'http://localhost:9200/bank/_mapping/account' -d '
2 {       
3   "properties": {
4         "state": {  
5             "type": "text",
6             "fielddata": true
7         }       
8     }         
9 }'
# bank是index、account是类型、state是你需要设置的text字段
复制代码

出现如下提示,说明设置成功:

1 {"acknowledged":true}

至此,聚合问题解决:

复制代码
 1 ➜  Downloads curl -XPOST 'localhost:9200/bank/_search?pretty' -d '        
 2         {
 3           "size": 0,
 4           "aggs": {
 5             "group_by_state": {
 6               "terms": {
 7                 "field": "state"
 8               }
 9             }
10           }
11         }'
12 {
13   "took" : 60,
14   "timed_out" : false,
15   "_shards" : {
16     "total" : 5,
17     "successful" : 5,
18     "failed" : 0
19   },
20   "hits" : {
21     "total" : 1000,
22     "max_score" : 0.0,
23     "hits" : [ ]
24   },
25   "aggregations" : {
26     "group_by_state" : {
27       "doc_count_error_upper_bound" : 20,
28       "sum_other_doc_count" : 770,
29       "buckets" : [
30         {
31           "key" : "id",
32           "doc_count" : 27
33         },
34         {
35           "key" : "tx",
36           "doc_count" : 27
37         },
38         {
39           "key" : "al",
40           "doc_count" : 25
41         },
42         {
43           "key" : "md",
44           "doc_count" : 25
45         },
46         {
47           "key" : "tn",
48           "doc_count" : 23
49         },
50         {
51           "key" : "ma",
52           "doc_count" : 21
53         },
54         {
55           "key" : "nc",
56           "doc_count" : 21
57         },
58         {
59           "key" : "nd",
60           "doc_count" : 21
61         },
62         {
63           "key" : "me",
64           "doc_count" : 20
65         },
66         {
67           "key" : "mo",
68           "doc_count" : 20
69         }
70       ]
71     }
72   }
73 }
复制代码
### Elasticsearch 中启用 Fielddata 或使用 Keyword 字段的解决方案 在 Elasticsearch 中,`text` 类型字段默认禁用 `fielddata`,这是为了防止内存占用过高。当需要对 `text` 字段进行排序、聚合或脚本访问时,会遇到类似以下错误信息:`Fielddata is disabled on text fields by default. Set fielddata=true on [publishDate] in order to load fielddata in memory by uninverting the inverted index.`[^2] #### 解决方案 1:启用 Fielddata 如果确实需要对 `text` 字段启用 `fielddata`,可以通过修改字段映射来实现。以下是具体操作步骤: 1. **更新字段映射** 使用 `_mapping` API 更新索引中的字段定义,将 `fielddata` 设置为 `true`。 ```json PUT /bbs/_mapping { "properties": { "publishTime": { "type": "text", "fielddata": true } } } ``` 注意:启用 `fielddata` 可能导致内存占用显著增加,因此需要根据实际需求谨慎使用[^2]。 2. **监控 Fielddata 内存使用情况** 为了确保性能稳定,建议定期监控 `fielddata` 的内存使用情况。可以使用以下命令查看相关统计信息: - 查看索引级别的 `fielddata`: ```bash GET /_cat/fielddata?v ``` - 查看主机级别的 `fielddata`: ```bash GET /_stats/fielddata?level=indices ``` - 查看字段级别的 `fielddata`: ```bash GET /_nodes/stats/indices/fielddata?fields=* ``` 这些命令可以帮助识别哪些字段占用了较多内存[^3]。 #### 解决方案 2:使用 Keyword 字段替代 更推荐的方式是使用 `keyword` 类型字段替代 `text` 字段进行排序和聚合操作。Elasticsearch 支持通过 `multi-fields` 定义同时包含 `text` 和 `keyword` 类型的字段。 1. **定义多字段映射** 在创建索引时,定义一个包含 `text` 和 `keyword` 子字段的字段结构: ```json PUT /bbs { "mappings": { "properties": { "publishTime": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } } } ``` 2. **使用 Keyword 字段进行排序或聚合** 在查询中,使用 `publishTime.keyword` 字段进行排序或聚合操作: ```json POST /bbs/_search { "sort": [ { "publishTime.keyword": { "order": "asc" } } ] } ``` 这种方式避免了启用 `fielddata` 带来的内存问题,同时提供了高效的排序和聚合能力[^1]。 ### 总结 - 如果必须对 `text` 字段启用 `fielddata`,可以通过更新字段映射实现,但需注意内存开销。 - 更优的解决方案是使用 `keyword` 类型字段替代 `text` 字段进行排序和聚合操作,通过 `multi-fields` 实现两者的兼容性。 ```python # 示例代码:Python 脚本更新字段映射 from elasticsearch import Elasticsearch es = Elasticsearch() # 更新字段映射 es.indices.put_mapping( index="bbs", body={ "properties": { "publishTime": { "type": "text", "fielddata": True } } } ) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值