最近在搞es的查询和,需要使用到模糊查询 匹配
在之前使用的时候,java 中的String 在 es 默认建立的mapping type是 String 是可以模糊查询的 ,但是新版的ES 废弃了 string 变为 text 和 keyword
这样一来 不管是 trem 还是 fuzzy 查询都不能查询 (也有可能是我个人写法问题,后续在研究下)
一开始想法很天真 很简单 就想修改es 的mapping ,比如我的其中一个字段 title ES默认建立的mapping 是如下格式
使用 -XGET http://192.168.136.128:9200/motor_fans_short_topic/_mapping?pretty 查看 新建的 index 的mapping
title" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
就很天真的通过 curl 将 title 修改为 text :String
curl -XPOST "http://192.168.136.128:9200/motor_fans_short_topic/motor_fans_short_topic/_mapping?pretty" -d '{
"motor_fans_short_topic": {
"properties": {
"title":{
"type":"string"
}
}
}
}'
很可惜 不支持 POST 直接报错 (吐槽下 安装的crul 很坑爹 ,真想打死公司的运维 什么都有问题 这只是第一个问题)
修改 put 很可惜 还是报错 405 是 不支持 大概意思是 确实 请求 head 坑爹吧 这不是默认的吗 好吧 加参数
-H "Content-Type:application/json"
curl -XPUT "http://192.168.136.128:9200/motor_fans_short_topic/motor_fans_short_topic/_mapping?pretty" -H "Content-Type:application/json" -d '{
"motor_fans_short_topic": {
"properties": {
"title":{
"type":"string"
}
}
}
}'
不好意思 还错,查了下 Elasticsearch的 mapping 一旦新建 只能新增字段 不能修改,其实想想马上理解,人家都分词什么的做好,你突然修改人家之前的工作都白做了,要你你乐意
所以到此 对于新接触的我来说 有点懵了,默认新建的不能使用不符合业务需求,默认新建的不能修改,有无法使用post 创建 index (其实是可以的,我的错)
到此我就觉得是时候安装 IK 了 ,所以 开始安装 IK 分词了
IK 的分词很简单,参照官网安装就可以了 https://github.com/medcl/elasticsearch-analysis-ik
安装好之后 测试,发现中文分词就是有问题,是编码问题,也不想修改别人的系统,找替代
我删除了所有我在ES中创建的现有 index
curl -XDELETE 'http://192.168.136.128:9200/motor_fans_short*'
请慎用 很有威力
我觉得放弃使用 crul 使用 psotman 操作
创建成功 很好,
如果index 不存在 使用如下方式 在创建 index 的 同时 创建 mapping
之后创建 对应的mapping :
http://192.168.136.128:9200/motor_fans_short_topic
{
"settings" : {
"analysis" : {
"analyzer" : {
"ik" : {
"tokenizer" : "ik_max_word"
}
}
}
},
"mappings" : {
"motor_fans_short_topic" : {
"dynamic" : true,
"properties" : {
"intro" :
{ "type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"title" : {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}
只想修改了title 和 intro的默认 匹配 ,所有 值创建对应的,其他字段采用默认mapping 创建成功
如果 已经创建 index 则使用如下方式:
http://192.168.136.128:9200/motor_fans_short_topic/motor_fans_short_topic/_mapping
{
"properties" : {
"intro" :
{ "type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"title" : {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
注意两者的区别,其实一样,只是主要mapping 创建好之后只能 新增字段 不能修改已经有的字段
之后 使用 已有的 API 接口往ES中插入数据 重新 查看 mapping
title 和 intro 都是设置默认。
再次使用term 查询 查询成功。目前 业务 提供jar 讲数据写入 kafka ,kafka consumer端写入es 分词完成,模糊查询完成
剩下还有一项工作,就是要将历史数据导入ES 中
有三种方案 :
第一种:写程序,链接MYSQL,批量的写入kakfa中,后续在现有逻辑已经完成,可以好low啊 而且麻烦
第二种:使用kafka的connect 从 mysql 导入 kafka ,kafka的consumer 程序写入ES中
第二种:直接从数据库中写入 ES中,最直接 最省事
寻找从MYSQL写入ES的方案。使用另外一篇记录遇到的坑吧