【轉】elasticsearch中字段類型默認顯示{ "foo": { "type": "text", "fields": { "keyword": {"type": "keyword", "ignore_above": 256} }


官方原文鏈接:https://www.elastic.co/cn/blog/strings-are-dead-long-live-strings

轉載原文連接:https://segmentfault.com/a/1190000008897731

Text vs. keyword

隨着ElasticSearch 5.0的到來, 同時也迎來了該版本的重大特性之一: 移除了string類型. 這個變動的根本原因是string類型會給我們帶來很多困惑: 因為ElasticSearch對字符串擁有兩種完全不同的搜索方式. 你可以按照整個文本進行匹配, 即關鍵詞搜索(keyword search), 也可以按單個字符匹配, 即全文搜索(full-text search). 對ElasticSearch稍有了解的人都知道, 前者的字符串被稱為not-analyzed字符, 而后者被稱作analyzed字符串.

事實上, 同一種類型用於應對兩種不同的使用場景是會讓人崩潰的, 因為有些選項只對其一的場景設置有效.例如position_increment_gapnot-analyzed字符就不會起作用, 而像ignore_above對於analyzed字符串就很難區分它到底是對整個字符串的值有效還是對單獨的每個分詞有效(在這種場景, ignore_above確實只對整個字符串值有效, 而對單個分詞的限制可以使用limit設置).

為了避免上述尷尬, string字段被拆分成兩種新的數據類型: text用於全文搜索的, 而keyword用於關鍵詞搜索.

新的默認類型

做了這個類型分解之后, 我們對string字段的默認dynamic mappings 也做了改變. 在以前剛接接觸ElasticSearch時, 如果需要對某個字段的所有取值做聚合, 你不得不對這些數據重做索引. 假如你正在處理的文檔中包含一個city字段. 對這個字段做聚合的話會分別給出newyork的總數, 而非我們通常期望的New York的總數.讓人沮喪的是為了達到我們希望的結果, 我們必須對這個字段重新進行索引.

為了不讓事情變得這么糟糕, ElasticSearch決定從Logstash中借取思路: 字符串將默認被同時映射成textkeyword類型. 例如對下面的文檔進行索引后:

{
    "foo": "bar"
}

  

ElasticSearch將會為你創建下面的動態映射(dynamic mappings):

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

  

當然, 基於這個映射你即可以在foo字段上進行全文搜索, 也可以通過foo.keyword字段實現關鍵詞搜索及數據聚合.

禁用這個特性也很方便: 你只需要在定義mapping時顯式聲明字符串字段的類型或者使用一個動態模板(dynamic template)來匹配你所有的字符串字段即可. 例如通過下面的dynamic template就可以恢復到在ElasticSearch 2.x中使用的dynamic template的效果:

{
    "match_mapping_type": "string",
    "mapping": {
        "type": "text"
    }
}

  

如何遷移到新版本

通常, 遷移工作是非常容易的. 以前映射到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
    }
}

  

如上所述, string字段被重新定義為textkeyword字段. 對於上面的index屬性, 因為在新的定義中我們不需要三種狀態(在以前的string定義中可以是analyzednot_analyzedno), 所以只簡單的定義成了boolean值, 以告知ElasticSearch是否可在該字段上進行搜索.

向后兼容

因為大的版本升級本身就充滿挑戰, 因此我們盡力不讓在在升級ElasticSearch過程中更新你的mapping字義. 首先, string字段可以繼續在已定義的2.x版本的索引中繼續使用, 而當創建新的索引時, ElasticSearch會做些處理以自動把string映射成等價的textkeyword. 如果在你已有的索引模板(index template)中定義有string字段, 這一點將非常有用, 因為這些模板無須改動即可使用到ElasticSearch 5.x中. 話說回來, 你還是需要着手做這些模板做些升級, 因為在ElasticSearch 6.0中我們可能會移除這個向后兼容的邏輯.

閱讀 13.9k 更新於 2017-04-01

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM