背景
项目有需要做一个同义词搜索的功能,就去研究了下es的同义词搜索功能,踩了不少坑记录下
同义词本地文件读取方式
如果只是需要同义词搜索,不需要管理和更新,es本体就能支持,我踩的坑基本也不在这,就不具体说了,参考这个就好了https://blog.csdn.net/qq_40592041/article/details/108006994
使用(dynamic-synonym)插件远程热词更新
拉取仓库代码
插件仓库地址https://github.com/bells/elasticsearch-analysis-dynamic-synonym
gitee有克隆的仓库,github连不上可以去gitee找找
根据自己的es版本打包
查询es版本直接请求es ip+端口就行
http://127.0.0.1:9200/
返回的json version里面就是版本
{"name" : "e8d7d490ec4f","cluster_name" : "elasticsearch","cluster_uuid" : "Hf1KFT2bSnaW00s9eLSK4Q","version" : {"number" : "7.4.2","build_flavor" : "default","build_type" : "docker","build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96","build_date" : "2019-10-28T20:40:44.881551Z","build_snapshot" : false,"lucene_version" : "8.2.0","minimum_wire_compatibility_version" : "6.8.0","minimum_index_compatibility_version" : "6.0.0-beta1"},"tagline" : "You Know, for Search"
}
找到pom文件修改version版本和es版本一致
这个时候有个问题,部分版本回出现打包失败的问题,第一种解决方案是去git提交历史里找最接近的版本,比如我是7.4.2版本,我找的就是支持7.7.0的提交记录,回滚代码到对应记录,在改version为7.4.2打包
打包后运行发现还是有问题,会报NoSuchMethodError,说output不存在,于是我把git记录往后推,到了改版本前,这个时候打包也会报output找不到的问题,这个时候把代码里报错的outputs(),改成outputs,不是调方法,而是掉对象,在打包就行了
打完包后在\target\releases文件夹中有个压缩包,解压上传到es的plugins文件夹里新建的dynamic-synonym文件夹就行
然后重启es,我这边是docker部署的,直接docker restart就行
服务端代码
我这边为了测试是给的死数据,后续需要按需修改,一开始我以为只要有放回就行,后来发现还需要对head做处理才行
@GetMapping("/getActive")public String getActiveEsSynonyms(HttpServletRequest request, HttpServletResponse response) {String result = "";String eTag = request.getHeader("If-None-Match");String modified = request.getHeader("If-Modified-Since");String currentDate = DateUtils.getTime();System.out.println("加载ik同义词,上次同义词:" + eTag + ",上次修改时间:" + modified + ",当前日期:" + currentDate);// if (!currentDate.equals(modified)) {String oldSynonym = 2+"";// System.out.println("加载ik同义词,当前同义词数:"+2);
// if (!oldSynonym.equals(eTag)) {// 获取数据库同义词
// List<Synonym> all = synonymService.all();
// StringBuilder words = new StringBuilder();
// for (Synonym synonym : all) {
// // 可以使用“=>”方式或者直接“,”分割形式,自行考虑应用场景
// String theWord = StringUtils.join(synonym.getWords(), " => ", synonym.getSynonymWords());
// words.append(theWord);
// words.append("\n");
// }eTag = oldSynonym;modified = currentDate;result = "苹果,手机\nns,游戏机";
// }
// }//更新时间response.setHeader("Last-Modified", modified);response.setHeader("ETag", eTag);response.setHeader("Content-Type", "text/plain");return result;}
设置es索引
如果是新建索引直接新建就好
PUT test
{"settings": {"index": {"number_of_shards": "3","number_of_replicas": "1","max_result_window": "200000","analysis": {"filter": {"remote_synonym": {"type": "dynamic_synonym","synonyms_path": "http://ip:port/synonyms/getActive","interval": 30},"local_synonym": {"type": "dynamic_synonym","synonyms_path": "synonym.txt"}},"analyzer": {"ik_max_syno": {"type": "custom","tokenizer": "ik_max_word","filter": ["remote_synonym"]}}}}},"mappings": {"properties": {"keyword": {"type": "text","analyzer": "ik_max_syno"}}}
}
如果是已有索引要修改,我的操作是先新建一个结构一样的索引,在把数据复制过去,在删除原索引,新建原索引,数据复制回去,删除新索引
删除索引命令
DELETE test
数据复制命令
POST _reindex
{"source": {"index": "原索引"},"dest": {"index": "目标索引"}
}
测试
添加数据后测试,搜索苹果能出现手机就说明没问题了