在es中,text類型的字段使用一種叫做fielddata的查詢時內存數據結構。當字段被排序,聚合或者通過腳本訪問時這種數據結構會被創建。它是通過從磁盤讀取每個段的整個反向索引來構建的,然后存存儲在java的堆內存中。
fileddata默認是不開啟的。Fielddata可能會消耗大量的堆空間,尤其是在加載高基數文本字段時。一旦fielddata已加載到堆中,它將在該段的生命周期內保留。此外,加載fielddata是一個昂貴的過程,可能會導致用戶遇到延遲命中。這就是默認情況下禁用fielddata的原因。如果嘗試對文本字段進行排序,聚合或腳本訪問,將看到以下異常:
“Fielddata is disabled on text fields by default. Set fielddata=true
on [your_field_name
] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.”
在啟用fielddata之前,請考慮使用文本字段進行聚合,排序或腳本的原因。這樣做通常沒有意義。text字段在索引例如New York這樣的詞會被分詞,會被拆成new,york。在此字段上面來一個terms的聚合會返回一個new的bucket和一個york的bucket,當你想只返回一個New York的bucket的時候就會出現問題。在kibana中執行如下的命令即可:
PUT my_index { "mappings": { "_doc": { "properties": { "my_field": { "type": "text", "fields": { "keyword": { "type": "keyword" } } } } } } }
然后使用my_field字段進行搜索。使用my_field.keyword字段進行聚合,排序或腳本。
可以使用PUT映射API在現有文本字段上啟用fielddata,如下所示:
PUT my_index/_mapping/_doc { "properties": { "my_field": { "type": "text", "fielddata": true } } }
為my_field指定的映射應包含該字段的現有映射以及fielddata參數。