参考: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
字段. 对这个字段做聚合的话会分别给出new
和york
的总数(全文搜索), 而非我们通常期望的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。请注意,这可以使用大量的内存。