ES全文检索支持拼音和繁简检索
- [1. 实现目标](#1. 实现目标)
- [2. 引入pinyin插件](#2. 引入pinyin插件)
-
- [2.1 编译 elasticsearch-analysis-pinyin 插件](#2.1 编译 elasticsearch-analysis-pinyin 插件)
- [2.2 安装拼音插件](#2.2 安装拼音插件)
- [3. 引入ik分词器插件](#3. 引入ik分词器插件)
-
- [3.1 已有作者编译后的包文件](#3.1 已有作者编译后的包文件)
- [3.2 只有源代码的版本](#3.2 只有源代码的版本)
- [3.3 安装ik分词插件](#3.3 安装ik分词插件)
- [4. 建立es索引](#4. 建立es索引)
- 5.测试检索
- [6. 繁简转换](#6. 繁简转换)
1. 实现目标
ES检索时无论输入简体还是繁体都要能够被检索到,例如检索时输入"語法"或者"语法",检索结果中无论是简体繁体都务必要被命中。
并且也要正确的高亮返回
2. 引入pinyin插件
拼音分词器(pinyin analyzer)通常需要自行引入,因为它不是 Elasticsearch 的默认分词器。可以使用 Elasticsearch 的插件来引入 pinyin 分词器,以便在索引中使用它。
2.1 编译 elasticsearch-analysis-pinyin 插件
选择与自己版本一致的版本,插件地址:
https://github.com/medcl/elasticsearch-analysis-pinyin/releases
elasticsearch-analysis-pinyin分词器目前没有下载即可使用的安装包,需要自己下载源码进行编译。可以在项目目录elasticsearch-analysis-pinyin\target\releases
看到编译后的结果elasticsearch-analysis-pinyin-7.17.11.zip
2.2 安装拼音插件
然后在es的安装目录下plugins目录下新建pinyin目录,并将解压后的文件复制到该目录下
重启es,启动日志中已经加载了拼音插件
3. 引入ik分词器插件
GitHub下载地址:Releases · infinilabs/analysis-ik · GitHub
3.1 已有作者编译后的包文件
选择与所需es版本相同的ik分词器,下载已经打包后的.zip文件
3.2 只有源代码的版本
首先下载源码解压后使用idea打开,修改es版本与分词器版本相同
使用 mvn clean install 打包时报错:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project elasticsearch-analysis-ik: Compilation failure
[ERROR] /D:/PersonalProjects/analysis-ik-7.17.11/analysis-ik-7.17.11/src/main/java/org/elasticsearch/index/analysis/IkAnalyzerProvider.java:[13,9] 无法将类 org.elasticsearch.index.analysis.AbstractIndexAnalyzerProvider<T>中的构造器
AbstractIndexAnalyzerProvider应用到给定类型;
[ERROR] 需要: org.elasticsearch.index.IndexSettings,java.lang.String,org.elasticsearch.common.settings.Settings
[ERROR] 找到: java.lang.String,org.elasticsearch.common.settings.Settings
修改代码报错部分:增加indexSetting参数到super入参的第一个位置
使用mvn clean install进行打包,注意我们所需的是/target/release目录下的.zip压缩包
3.3 安装ik分词插件
将下载或者编译后的.zip文件解压到es的安装目录下的plugins目录下,并重命名为ik
然后启动es,查看日志可发现已经加载的ik分词器
常规的最常用的使用方式就是,数据插入存储时用 ik_max_word模式分词,而检索时,用ik_smart模式分词,即:索引时最大化的将文章内容分词,搜索时更精确的搜索到想要的结果。
建立映射示例如下:在数据被索引时我们设置"analyzer": "ik_max_word",在检索时指定"search_analyzer": "ik_smart"
4. 建立es索引
setting.json
json
{
"aliases": {
},
"settings": {
"index": {
"refresh_interval": "3s",
"number_of_shards": "3",
"number_of_replicas": "1",
"max_inner_result_window": "10000",
"max_result_window": "20000",
"analysis": {
"filter": {
"pinyin_full_filter": {
"keep_joined_full_pinyin": "true",
"lowercase": "true",
"keep_original": "false",
"keep_first_letter": "false",
"keep_separate_first_letter": "false",
"type": "pinyin",
"keep_none_chinese": "false",
"limit_first_letter_length": "50",
"keep_full_pinyin": "true"
},
"pinyin_simple_filter": {
"keep_joined_full_pinyin": "true",
"lowercase": "true",
"none_chinese_pinyin_tokenize": "false",
"padding_char": " ",
"keep_original": "true",
"keep_first_letter": "true",
"keep_separate_first_letter": "false",
"type": "pinyin",
"keep_full_pinyin": "false"
}
},
"analyzer": {
"pinyinFullIndexAnalyzer": {
"filter": [
"asciifolding",
"lowercase",
"pinyin_full_filter"
],
"type": "custom",
"tokenizer": "ik_max_word"
},
"pinyinSimpleIndexAnalyzer": {
"filter": [
"pinyin_simple_filter",
"lowercase"
],
"type": "custom",
"tokenizer": "ik_max_word"
},
"ik_pinyin_analyzer": {
"filter": [
"asciifolding",
"lowercase",
"pinyin_full_filter",
"word_delimiter"
],
"type": "custom",
"tokenizer": "ik_smart"
},
"ikIndexAnalyzer": {
"filter": [
"asciifolding",
"lowercase",
"pinyin_full_filter",
"word_delimiter"
],
"type": "custom",
"tokenizer": "ik_max_word"
}
}
}
}
},
"mappings": {
"dynamic": "false"
}
}
mapping.json
json
{
"properties": {
"nickName": {
"type": "text",
"analyzer": "ikIndexAnalyzer",
"search_analyzer": "ik_pinyin_analyzer",
"fields": {
"full": {
"type": "text",
"analyzer": "pinyinFullIndexAnalyzer"
},
"simple": {
"type": "text",
"analyzer": "pinyinSimpleIndexAnalyzer"
}
}
}
}
}
mapping.json 文件定义了 Elasticsearch 索引中的字段映射和分析器设置:
-
analyzer :定义了在索引时使用的分析器。在搜索时会用这个分析器来处理查询字符串,使之与索引中的文本数据匹配。
ikIndexAnalyzer
分析器使用了ik_max_word
分词器(tokenizer),并应用了一系列过滤器(filter),包括 ASCII 折叠、小写转换、拼音处理和词分割。 -
search_analyzer :定义了在搜索时使用的分析器。
ik_pinyin_analyzer
分析器用于处理查询字符串,在进行搜索时与索引中的数据进行匹配。 -
fields :定义了为同一个字段创建不同的索引方式。在这个示例中,为
nickName
字段创建了两个额外的索引方式:full
和simple
。-
full :使用了
pinyinFullIndexAnalyzer
分析器,它将nickName
字段的文本进行全拼音分析,用于支持全拼音搜索。 -
simple :使用了
pinyinSimpleIndexAnalyzer
分析器,它将nickName
字段的文本进行简拼音分析,用于支持简拼音搜索。
-
5.测试检索
新增测试数据
json
PUT /zzt_works/_doc/2
{
"nickName":"語法講義"
}
PUT /zzt_works/_doc/3
{
"nickName":"语法讲义"
}
中文简写查询
中文繁体查询
拼音全拼查询
拼音简拼查询
6. 繁简转换
如果需求只需要繁简转换,可使用以下设置和映射配置
index.json
json
{
"aliases": {
},
"settings": {
"index": {
"refresh_interval": "3s",
"number_of_shards": "3",
"number_of_replicas": "1",
"max_inner_result_window": "10000",
"max_result_window": "20000",
"analysis": {
"filter": {
"pinyin_full_filter": {
"keep_joined_full_pinyin": "true",
"lowercase": "true",
"keep_original": "false",
"keep_first_letter": "false",
"keep_separate_first_letter": "false",
"type": "pinyin",
"keep_none_chinese": "false",
"limit_first_letter_length": "50",
"keep_full_pinyin": "true"
}
},
"analyzer": {
"ik_pinyin_analyzer": {
"filter": [
"asciifolding",
"lowercase",
"pinyin_full_filter",
"word_delimiter"
],
"type": "custom",
"tokenizer": "ik_smart"
},
"ikIndexAnalyzer": {
"filter": [
"asciifolding",
"lowercase",
"pinyin_full_filter",
"word_delimiter"
],
"type": "custom",
"tokenizer": "ik_max_word"
}
}
}
}
},
"mappings": {
"dynamic": "false"
}
}
mapping.json
json
{
"properties": {
"nickName": {
"type": "text",
"analyzer": "ikIndexAnalyzer",
"search_analyzer": "ik_pinyin_analyzer"
}
}
}