【转】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
相关文章
相关标签/搜索