1.安装ik分词器
每个节点安装
bin 目录为Elasticsearch的脚本目录 bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/<es_version> 例如es 的版本为7.16.1 bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/7.16.1
离线安装 先把插件下载
bin/elasticsearch-plugin install file:<插件目录> (绝对路径)
安装完之后重启es集群
验证是否安装成功
curl -x GET -u <user>:<password> <ip>:9200/_cat/plugins?v
2.配置自定义词库 (非必须)
1.静态文件(更新词库需重启集群)
1.配置文件
在es 的config目录下找到 ik的配置
cd analysis-ik # IKAnalyzer.cfg.xml文件 vim IKAnalyzer.cfg.xml
2.创建词库文件
文本格式是UTF8编码
在当前目录下创建一个 custom_extend_word.dic (最好是copy一个dic文件重命名编辑)
custom_extend_word.dic 文件内容 每一行就是一个词
3.修改文件内容
vim IKAnalyzer.cfg.xml
1.<entry key="ext_dict"></entry> 分词词库 2.<entry key="ext_stopwords"></entry> 屏蔽的词库
示例:
<entry key="ext_dict">custom_extend_word.dic</entry>
4.重启es集群
2.热加载(更新词库不需要重启)
热加载的方式需要提供一个接口,es集群分每一分钟会获取这个接口中的数据,如果词库有变更会加载到词库中,不需要重启es集群
1.编写http接口
# python 代码 使用flask写的一个http接口示例 import os import hashlib import time from flask import Flask, Response, request app = Flask(__name__) # 存放单词列表文件的路径 word_list_file_path = 'words.txt' def get_file_last_modified(): """返回单词列表文件的最后修改时间。""" return os.path.getmtime(word_list_file_path) def get_etag(): """基于文件内容生成 ETag。""" with open(word_list_file_path, 'rb') as f: file_content = f.read() return hashlib.md5(file_content).hexdigest() @app.route('/getCustomDict', methods=['GET']) def get_custom_dict(): """处理获取自定义词典的请求。""" if not os.path.exists(word_list_file_path): return Response("未找到词汇列表文件。", status=404) # 获取文件的最后修改时间和 ETag last_modified = get_file_last_modified() etag = get_etag() # 获取客户端传来的 If-Modified-Since 和 If-None-Match 请求头 if_modified_since = request.headers.get('If-Modified-Since') if_none_match = request.headers.get('If-None-Match') # 检查文件是否发生变化 if if_modified_since and time.mktime( time.strptime(if_modified_since, '%a, %d %b %Y %H:%M:%S GMT')) >= last_modified: return Response(status=304) # 文件未修改 if if_none_match == etag: return Response(status=304) # 文件未修改 # 读取词汇列表文件,并以要求的格式返回 with open(word_list_file_path, 'r', encoding='utf-8') as f: word_list = f.read() # 返回词汇列表,并添加合适的 HTTP 头部 response = Response(word_list, mimetype='text/plain; charset=utf-8') response.headers['Last-Modified'] = time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(last_modified)) response.headers['ETag'] = etag return response if __name__ == '__main__': # 确保测试时词汇列表文件存在 if not os.path.exists(word_list_file_path): with open(word_list_file_path, 'w', encoding='utf-8') as f: f.write("word1\nword2\nword3\n") # 初始化词汇列表内容 # 启动 Flask 应用 app.run(debug=True, host='0.0.0.0', port=5000)
代码中的注释翻译:
-
get_file_last_modified
:-
这个函数返回词汇列表文件的最后修改时间,
os.path.getmtime
会返回文件的最后修改时间戳。
-
-
get_etag
:-
这个函数读取文件内容并基于文件内容生成一个 MD5 哈希值,作为 ETag。这可以用来检查文件是否发生了变化。
-
-
get_custom_dict
:-
这是处理
/getCustomDict
路由的函数,首先它检查文件是否存在,然后计算文件的最后修改时间和 ETag。 -
它会检查客户端请求中是否包含
If-Modified-Since
或If-None-Match
头部,如果文件未发生变化,就返回304 Not Modified
状态码。 -
如果文件有变化,它会返回最新的词汇内容,并包含适当的 HTTP 头部:
Last-Modified
和ETag
。
-
-
主程序 (
if __name__ == '__main__'
):-
这个部分确保在运行程序时,词汇列表文件 (
words.txt
) 存在。如果不存在,它会创建并写入一个初始的单词列表。 -
最后,使用
app.run()
启动 Flask 应用并监听在5000
端口。
-
使用说明:
-
初始化文件:如果
words.txt
文件不存在,程序会自动创建并写入一些默认的词汇(如word1\nword2\nword3
)。 -
处理 HTTP 请求:通过 GET 请求访问
http://localhost:5000/getCustomDict
,获取当前的词汇列表。如果文件被更新,Flask 会返回新的词汇列表,并设置合适的Last-Modified
和ETag
头部。 -
缓存机制:客户端可以通过发送
If-Modified-Since
或If-None-Match
头部来检查文件是否发生变化,如果没有变化,服务器会返回304 Not Modified
。 -
更新词汇:往
words.txt
文件中添加词汇即可
2.修改配置文件
# 远程扩展字典 <entry key="remote_ext_dict">url</entry> # 停止词字典 如果一些会查询的可以在这里设置,可以减少es的压力 例如:是,的,啦 <entry key="remote_ext_stopwords">words_location</entry> 示例 <entry key="remote_ext_dict">http://localhost:5000/getCustomDict</entry>
重启es集群
3.使用ik分词器
简介
ik_max_word:执行最细粒度的文本分割。例如,它将“中华人民共和国国歌”分割为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、人、民、共和国、共和、和、国国、国歌”,穷举生成各种可能的组合,适合Term Query。
ik_smart:执行文本的最粗粒度分割。例如,它将“中华人民共和国国歌”分割为“中华人民共和国、国歌”,适合词组查询。
注意:ik_smart 不是 ik_max_word 的子集。