昨天同事触发定时任务发现es相关服务报了一个序列化问题,
今天早上捕获异常将异常堆栈全部打出来看,才发现是聚合的字段不是keyword类型的问题。
到kibbna命令行执行也是一样的错误
使用 /_mapping查看索引的字段类型,才发现userUniqueid是text类型
如果用text执行聚合,还必须在字段名后面加上 userUniqueid.keyword才能聚合。
需要重新建索引,指定类型!
这里说说text和keyword的区别
Text
当一个字段是要被全文检索时,比如 Email 内容、产品描述,这些字段应该使用 text 类型。设置 text 类型以后,字段内容会被分析,在生成倒排索引之前,字符串会被分析器分成一个个词项。text类型的字段不用于排序,很少用于聚合。
注意事项
- 适用于全文检索:如 match 查询。
- 文本字段会被分词。
- 默认情况下,会创建倒排索引。
- 自动映射器会为 Text 类型创建 Keyword 字段。
Keyword
Keyword 类型适用于不分词的字段,如姓名、Id、数字等。如果数字类型不用于范围查找,用 Keyword 的性能要高于数值类型。
注意事项
- Keyword 不会对文本分词,会保留字段的原有属性,包括大小写等。
- Keyword 仅仅是字段类型,而不会对搜索词产生任何影响。
- Keyword 一般用于需要精确查找的字段,或者聚合排序字段。
- Keyword 通常和 Term 搜索一起用。
- Keyword 字段的
ignore_above
参数代表其截断长度,默认 256,如果超出长度,字段值会被忽略,而不是截断,忽略指的是会忽略这个字段的索引,搜索不到,但数据还是存在的。
那怎么将text类型修改为keyword呢?es不提供单个修改索引字段类型的方法,只能先创建一个中间索引(mappings里字段类型为keyword),然后将原索引数据迁移到这个索引里,再将原索引删除,创建一个新的原索引名的索引(注意mappings保持和中间索引一致),再将中间索引的数据迁移到新的索引里。删除中间索引。
从text类型修改为keyword类型
1 创建中间索引
PUT /tmp_index
{ "mappings":{
"properties": {
"appendixUrl": {
"type": "keyword",
"index": false,
"ignore_above": 256
},
"createTime": {
"type": "date"
},
"department": {
"type": "keyword",
"ignore_above": 256
},
"doctorName": {
"type": "keyword",
"ignore_above": 256
},
"firmId": {
"type": "keyword",
"ignore_above": 256
},
"grantUniqueId": {
"type": "keyword",
"ignore_above": 256
},
"hospitalNumber": {
"type": "keyword",
"ignore_above": 256
},
"notifyStatus": {
"type": "long"
},
"overdueSigned": {
"type": "keyword",
"ignore_above": 256
},
"patientCardNum": {
"type": "keyword",
"ignore_above": 256
},
"patientName": {
"type": "keyword",
"ignore_above": 256
},
"practicePlace": {
"type": "keyword",
"ignore_above": 256
},
"recipeInfo": {
"type": "keyword",
"index": false,
"ignore_above": 256
},
"refuseReason": {
"type": "keyword",
"index": false,
"ignore_above": 256
},
"selfAuthId": {
"type": "keyword",
"ignore_above": 256
},
"signTime": {
"type": "date"
},
"signedPdfUrl": {
"type": "keyword",
"index": false,
"ignore_above": 256
},
"stampLogId": {
"type": "keyword",
"index": false,
"ignore_above": 256
},
"status": {
"type": "long"
},
"subject": {
"type": "keyword",
"ignore_above": 256
},
"sysTag": {
"type": "keyword",
"ignore_above": 256
},
"tag": {
"type": "text",
"analyzer": "comma",
"fielddata": true
},
"uniqueid": {
"type": "keyword",
"ignore_above": 256
},
"upDefault1": {
"type": "keyword",
"ignore_above": 256
},
"upDefault2": {
"type": "keyword",
"ignore_above": 256
},
"updateTime": {
"type": "date"
},
"urid": {
"type": "keyword",
"ignore_above": 256
},
"userUniqueid": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
但因为未指定setting还报错
{
"error" : {
"root_cause" : [
{
"type" : "mapper_parsing_exception",
"reason" : "Failed to parse mapping [_doc]: analyzer [comma] has not been configured in mappings"
}
],
"type" : "mapper_parsing_exception",
"reason" : "Failed to parse mapping [_doc]: analyzer [comma] has not been configured in mappings",
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "analyzer [comma] has not been configured in mappings"
}
},
"status" : 400
}
需要将setting也指定
GET /索引名/_settings查看索引的setting
加上settings再创建索引
"settings" : {
"analysis" : {
"analyzer" : {
"comma" : {
"pattern" : ",",
"type" : "pattern"
}
}
}
}
2 迁移数据
POST _reindex?wait_for_completion=false
{
"source": {
"index": "源索引名"
},
"dest": {
"index": "tmp_index"
}
}
3 删除源索引
DELETE 源索引名
4 重建相同名称的源索引名索引
同步骤1的命令
5 迁移数据
同步骤2,将源和目标索引互换一下即可