分词器
规范化 normalization
字符过滤器 character filter
分词之前的预处理,过滤无用字符
分词器 tokenizer
切词用
常见的分词器
- standard analyzer:默认分词器,中文支持的不理想,会逐字拆分。
- pattern tokenizer:以正则匹配分隔符,把文本拆分成若干词项。
- simple pattern tokenizer:以正则匹配词项,速度比pattern tokenizer快。
- whitespace analyzer:以空白符分隔
中文分词器 ik
安装与部署
- ik下载地址: https://github.com/medcl/elasticsearch-analysis-ik
- 在es目录中的plugins下创建ik插件文件夹并解压
- 重启es
ik主要文件
IK分词器配置文件 IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict"></entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords"></entry> <!--用户可以在这里配置远程扩展字典 --> <!-- <entry key="remote_ext_dict">words_location</entry> --> <!--用户可以在这里配置远程扩展停止词字典--> <!-- <entry key="remote_ext_stopwords">words_location</entry> --> </properties>
字典 同目录下的dic文件
- 主词库 main.dic
- 停用词库 stopword.dic
- 计量单位词库 quantifier.dic
- 行政单位词库 suffix.dic
- 姓氏词库 surname.dic
- 语气词库 preposition.dic
- 扩展词库 extra_*.dic
不同类别的analyzer
- ik_max_word: 将文本做最细粒度的拆分,会穷尽各种可能的组合,适合 Term Query;
- ik_smart: 会做最粗粒度的拆分,适合 Phrase 查询。
eg:
post localhost:9200/_analyze{
{“text”:“中华人民共和国人民大会堂”,“analyzer”:“ik_max_word” }
}
热更新
接口更新:
- 通过编写符合规范的自定义的接口配置到ik配置文件的远程扩展字典位置 remote_ext_dict
规范: 一个utf-8编码格式的txt文件,
请求头中包含Last-Modified与
ETag 来确认字典更新.
通过mysql热更新.需要修改ik分词器源码.
org.wltea.analyzer.dic.Dictionary#loadMainDict方法里添加自定义的远程词库
/**
* 加载主词典及扩展词典
*/
private void loadMainDict() {
// 建立一个主词典实例
_MainDict = new DictSegment((char) 0);
// 读取主词典文件
Path file = PathUtils.get(getDictRoot(), Dictionary.PATH_DIC_MAIN);
loadDictFile(_MainDict, file, false, "Main Dict");
// 加载扩展词典
this.loadExtDict();
// 加载远程自定义词库
this.loadRemoteExtDict();
// 加载远程自定义词库
this.loadMySQLExtDict();
}
/**
* 从mysql加载热更新词典
*/
private void loadMySQLExtDict() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Path file = PathUtils.get(getDictRoot(), "jdbc-reload.properties");
prop.load(new FileInputStream(file.toFile()));
logger.info("jdbc-reload.properties");
for(Object key : prop.keySet()) {
logger.info("" + key + "=" + prop.getProperty(String.valueOf(key)));
}
logger.info(" hot dict " + prop.getProperty("jdbc.reload.sql") + "......");
conn = DriverManager.getConnection(
prop.getProperty("jdbc.url"),
prop.getProperty("jdbc.user"),
prop.getProperty("jdbc.password"));
stmt = conn.createStatement();
rs = stmt.executeQuery(prop.getProperty("jdbc.reload.sql"));
while(rs.next()) {
String theWord = rs.getString("word");
logger.info("hot word: " + theWord);
_MainDict.fillSegment(theWord.trim().toCharArray());
}
Thread.sleep(Integer.valueOf(String.valueOf(prop.get("jdbc.reload.interval"))));
} catch (Exception e) {
logger.error("erorr", e);
} finally {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
logger.error("error", e);
}
}
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
logger.error("error", e);
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
logger.error("error", e);
}
}
}
}
停用词mysql扩展同理.
mvn package 打包,替换原来的jar包,并补充需要的mysql连接依赖包.