筆者所有文章第一時間發(fā)布于:
hhbbz的個人博客
問題描述
今天在做es的聚合查詢的時候,遇到了一個問題。
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory."
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "megacorp",
"node": "-Md3f007Q3G6HtdnkXoRiA",
"reason": {
"type": "illegal_argument_exception",
"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory."
}
}
],
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory."
}
},
"status": 400
}
搜了一下應(yīng)該是5.x后對排序,聚合這些操作用單獨(dú)的數(shù)據(jù)結(jié)構(gòu)(fielddata)緩存到內(nèi)存里了,需要單獨(dú)開啟。
解決方法
遇到這個錯誤是因?yàn)槟銍L試對一個text類型的字段做排序,而text類型的字段是要分詞的。 一來詞典很大,性能會很差;二來排序結(jié)果是詞典里的詞,而并非整個text的內(nèi)容。 出于這2點(diǎn)原因,ES5.x以后對于text類型默認(rèn)禁用了fielddata,防止對text字段一些錯誤的操作(排序,聚合,script)而給heap造成很大的壓力。如果一定有對該字段按照文本字母序做排序的需求,可以將該字段定義為multi-filed。于是我選擇了將字段定義為keyword。keyword字段是通過doc values排序的,內(nèi)存消耗遠(yuǎn)小于fielddata。
Text和keyword的區(qū)別
ElasticSearch 5.0以后,string類型有重大變更,移除了string類型,string字段被拆分成兩種新的數(shù)據(jù)類型: text用于全文搜索的,而keyword用于關(guān)鍵詞搜索。
ElasticSearch字符串將默認(rèn)被同時映射成text和keyword類型,將會自動創(chuàng)建下面的動態(tài)映射(dynamic mappings):
{
"foo": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
這就是造成部分字段還會自動生成一個與之對應(yīng)的“.keyword”字段的原因。
Text:
會分詞,然后進(jìn)行索引
支持模糊、精確查詢
不支持聚合
keyword:
不進(jìn)行分詞,直接索引
支持模糊、精確查詢
支持聚合
結(jié)論
keyword類型滿足目前系統(tǒng)的需求,且能保證接口統(tǒng)一,所以建議將查詢、聚合中涉及的字符串類型,在mapping中設(shè)置為“keyword”。