【轉】elasticsearch中字段類型默認顯示{ "foo": { "type": "text", "fields&q...

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

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

Text vs. keyword

隨着ElasticSearch 5.0的到來, 同時也迎來了該版本的重大特性之一: 移除了string類型. 這個變更的根本緣由是string類型會給咱們帶來不少困惑: 由於ElasticSearch對字符串擁有兩種徹底不一樣的搜索方式. 你能夠按照整個文本進行匹配, 即關鍵詞搜索(keyword search), 也能夠按單個字符匹配, 即全文搜索(full-text search). 對ElasticSearch稍有了解的人都知道, 前者的字符串被稱爲not-analyzed字符, 然後者被稱做analyzed字符串.flex

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

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

新的默認類型

作了這個類型分解以後, 咱們對string字段的默認dynamic mappings 也作了改變. 在之前剛接接觸ElasticSearch時, 若是須要對某個字段的全部取值作聚合, 你不得不對這些數據重作索引. 假如你正在處理的文檔中包含一個city字段. 對這個字段作聚合的話會分別給出newyork的總數, 而非咱們一般指望的New York的總數.讓人沮喪的是爲了達到咱們但願的結果, 咱們必須對這個字段從新進行索引..net

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

{
    "foo": "bar"
}

  

ElasticSearch將會爲你建立下面的動態映射(dynamic mappings):blog

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

  

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

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

{
    "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
相關文章
相關標籤/搜索