随着ElasticSearch 5.X 系列的到来, 同时也迎来了该版本的重大特性之一: 移除了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中我们可能会移除这个向后兼容的逻辑.

Elasticsearch 中数据类型 text 与 keyword 的区别的更多相关文章

  1. Elasticsearch中text与keyword的区别

    text类型 1:支持分词,全文检索,支持模糊.精确查询,不支持聚合,排序操作; 2:test类型的最大支持的字符长度无限制,适合大字段存储: 使用场景: 存储全文搜索数据, 例如: 邮箱内容.地址. ...

  2. ES 15 - Elasticsearch中的数据类型 (text、keyword、date、geo等)

    目录 1 核心数据类型 1.1 字符串类型 - string(不再支持) 1.1.1 文本类型 - text 1.1.2 关键字类型 - keyword 1.2 数字类型 - 8种 1.3 日期类型 ...

  3. jQuery中的text(),html(),val()的区别

    一.jquery中HTML 1. 无参html() 方法用来获取任意元素的HTML内容,如果你调用多个选定元素的.html()方法,那么其读取的只是第一个元素,换句话说:如果选择器匹配多于一个的元素, ...

  4. jQuery中val() text()和html()的区别

    2020年4月21日 16:48:11 jQuery 学习 html() 它可以设置和获取起始标签和结束标签中的内容. 跟 dom 属性 innerHTML 一样.text() 它可以设置和获取起始标 ...

  5. JQuery中的text(),html()和val()区别

    定义和用法 text() 方法方法设置或返回被选元素的文本内容 代码如下 <!DOCTYPE html> <html lang="en"> <head ...

  6. ES索引Index相关操作&ES数据类型、字符串类型text和keyword区别

    1.查看索引以及删除之前的测试索引 1. 查看索引以及索引数量信息 liqiang@root MINGW64 ~/Desktop $ curl -X GET http://127.0.0.1:9200 ...

  7. 【转】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 ...

  8. SQL Server中Text和varchar(max) 区别

    SQL Server 2005之后版本:请使用 varchar(max).nvarchar(max) 和 varbinary(max) 数据类型,而不要使用 text.ntext 和 image 数据 ...

  9. js中的text(),html() ,val()的区别

    js中的text(),html() ,val()的区别 text(),html() ,val()三个方法用于html元素的存值和取值,但是他们各有特点,text()用于html元素文本内容的存取,ht ...

随机推荐

  1. DSL 系列(2) - 插件的论述与实现

    前言 本文主要探讨基于 DSL(domain specific language) 之上的插件设计,他们是领域的附属,为领域提供额外的服务,但领域不依赖于他们. 1. 论述 领域应当尽可能地去专注他的 ...

  2. TensorFlow 使用变量共享

    参考: https://www.tensorflow.org/programmers_guide/variable_scope 举例说明 TensorFlow中的变量一般就是模型的参数.当模型复杂的时 ...

  3. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 客户端多网络支持

    客户端可以支持灵活的,中间层连接选择,由于我们系统的定位架构大型信息系统的,所以全国各地,甚至国外的用户也会有,所以需要支持全网络配置,只要配置了中间层,可以选择连接哪个中间层的服务程序.客户端可以进 ...

  4. js变量以及其作用域

    一.变量的类型  Javascript和Java.C这些语言不同,它是一种无类型.弱检测的语言.它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变量.例如: ...

  5. 【转】RCP中org.eclipse.core.runtime.CoreException

    org.eclipse.core.runtime.CoreException: Plug-in TRAIN was unable to load class train.Application. 利用 ...

  6. 【问题解决方案】之 Word 公式编辑器 使用小tips

    输入空格:shift+Ctrl+space 换行:直接回车.之后在上方菜单栏中选择"在等号处对齐"

  7. 解决linux用户切换失败 su:execute /usr/bin 没有权限

    问题描述: 回宿舍前,在root用户中安装fish,并修改其shell为fish.回宿舍之后,在图形界面用root用户进行登陆,莫名其妙登陆失败.没有任何提示信息,直接回到登陆界面.用非root用户登 ...

  8. SQL server 生成数据字典

    Set nocount on ), ) DECLARE Tbls CURSOR FOR ),isnull(g.[value],'-')) AS TABLE_COMMENT FROM INFORMATI ...

  9. [转帖]nginx配置ssl加密(单/双向认证、部分https)

    nginx配置ssl加密(单/双向认证.部分https) https://segmentfault.com/a/1190000002866627   nginx下配置ssl本来是很简单的,无论是去认证 ...

  10. PHP二维数组(或任意维数组)转换成一维数组的方法汇总(实用)

    目录 1 array_reduce函数法 2 array_walk_recursive函数法 3 array_map函数法 假设有下面一个二维数组: $user = array( '0' => ...