聚合查詢,text類型數據報錯,Fielddata is disabled on text fields by default

參考:https://www.elastic.co/blog/strings-are-dead-long-live-strings

1、背景 

升級ESjar包的時候報錯(從Es 2.x升級到Es 5.x),報錯信息:Fielddata is disabled on text fields by default. Set fielddata=true on [org] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.

搜索ES的官方文檔,發現一段話:Es官方文檔

發現其實是字符類型的變化導致的問題。

2、分析

出現報錯的原因是因爲Es在5.x及以後的版本中將String類型去掉了,以text和keyWord代替。去掉string類型. 這個變動的根本原因是string類型會給我們帶來很多困惑: 因爲ElasticSearch對字符串擁有兩種完全不同的搜索方式. 你可以按照整個文本進行匹配, 即關鍵詞搜索(keyword search), 也可以按單個字符匹配, 即全文搜索(full-text search). 對ElasticSearch稍有了解的人都知道, 前者的字符串被稱爲not-analyzed字符, 而後者被稱作analyzed字符串.

關鍵詞搜索(keyword search) not-analyzed
全文搜索(full-text search) analyzed

string字段被拆分成兩種新的數據類型: text用於全文搜索的, 而keyword用於關鍵詞搜索.

關於兩種搜索方式,舉個例子:假如你正在處理的文檔中包含一個city字段. 對這個字段做聚合的話會分別給出newyork的總數(全文搜索), 而非我們通常期望的New York的總數(關鍵詞搜索).讓人沮喪的是爲了達到我們希望的結果, 我們必須對這個字段重新進行索引.

ElasticSearch創建的動態映射(dynamic mappings)的區別

Es 2.x

{
    "foo": {
        "type": "string",
        "index": "not_analyzed"
    }
}

ES 5.x

{
    "foo": {
        "type": "text",
        "fields": {
            "keyword": {
                "type": "keyword",
                "ignore_above": 256
            }
        }
    }
}

3、解決辦法

將text聚合的改爲keyword聚合:

(1)以前映射到analyzed的字符串的字段:

{
    "foo": {
        "type": "string",
        "index": "analyzed"
    }
}

如今只要映射爲text即可:

{
    "foo": {
        "type": "text",
        "index": true
    }
}

以前被定義爲not_analyzed的字符串字段:

{
    "foo": {
        "type": "string",
        "index": "not_analyzed"
    }
}

也只需要被定義爲keyword即可:

{
    "foo": {
        "type": "keyword",
        "index": true
    }
}

(2)除了這個方法以外還有一種方式就是 Set fielddata=true on [org]

如果您嘗試對text 字段上的腳本進行排序,聚合或訪問值,則會看到以下異常:

Fielddata默認情況下禁用文本字段。fielddata=true在[ your_field_name] 上設置,以便通過取消倒置索引來加載內存中的fielddata。請注意,這可以使用大量的內存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章