一、概念
注意事项
为了避免搜索同音字,搜索时不要使用拼音分词器
二、拼音分词器
官网https://github.com/medcl/elasticsearch-analysis-pinyin
安装
注意与elasticsearch的对应关系
下载
我们的ES使用了7.15.1,所以我们使用master分支代码。打开官网,下载master分支的zip代码
https://codeload.github.com/medcl/elasticsearch-analysis-pinyin/zip/refs/heads/master
解压
unzip elasticsearch-analysis-pinyin-master.zip
编译
主要修改pom.xml中ES的版本号,需要对应你安装的es的版本
<properties>
<elasticsearch.version>7.15.1</elasticsearch.version>
...
</properties>
- 方法一 直接mvn package
注意jdk要1.8以上,打开cmd,cd到解压后的文件夹目录
mvn package
- 方法二 在idea中编译
打包好了过后,当前目录多了一个target文件夹,点击进入就会在releases下面生成zip安装包
配置ES
在releases文件夹下面,解压zip包
unzip elasticsearch-analysis-pinyin-7.15.1.zip
# 重命名文件py
mv elasticsearch-analysis-pinyin-7.15.1.zip py
将文件移动到ES的plugins目录
因为我的es是docker安装,所以目录是:/usr/local/elasticsearch/plugins
重启ES
docker restart elasticsearch
查看启动日志
切记分词器的版本号一定要与ES的安装版本号一一致
体验效果
# 测试拼音分词器
POST /_analyze
{
"text": ["如家酒店还不错"],
"analyzer": "pinyin"
}
三、自定义分词器
使用了拼音分词器之后,导致汉字分词没有了,大部分场景还是需要汉字分词,包括内容有表情符号的。所以需要自定义分词器;
概念
如何创建自定义分词器
- 创建索引库时,在settings中配置,可以包含三部分
- character filter
- tokenizer
- filter
在创建索引库时,通过settings来配置自定义的analyzer(分词器)
filter中属性可以参照官网
创建自定义分词器
# 自定义分词器
PUT /test
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer":{
"tokenizer":"ik_max_word",
"filter":"py"
}
},
"filter": {
"py":{
"type":"pinyin",
"keep_full_pinyin":false,
"keep_joined_full_pinyin":true,
"keep_original":true,
"limit_first_letter_length":16,
"remove_duplicated_term":true,
"none_chinese_pinyin_tokenize":false
}
}
}
},
"mappings": {
"properties": {
"name":{
"type": "text",
"analyzer": "my_analyzer"
}
}
}
}
测试
# 测试自定义分词器
POST /test/_analyze
{
"text": ["如家酒店还不错"],
"analyzer": "my_analyzer"
}
测试demo
准备数据
# 插入测试文档
POST /test/_doc/1
{
"id":1,
"name":"狮子"
}
POST /test/_doc/2
{
"id":2,
"name":"虱子"
}
测试搜索
GET /test/_search
{
"query":{
"match": {
"name": "shizi"
}
}
}
问题思考,当我们搜索狮子时,虱子也被搜出,为了避免搜索同音字,搜索时不要使用拼音分词器
原因如下:
解决办法
在创建倒排索引时应该用my_analyzer分词器;字段在搜索时应该使用ik_smart分词器
先删除索引,在创建
# 先删除
DELETE /test
# 自定义分词器
PUT /test
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer":{
"tokenizer":"ik_max_word",
"filter":"py"
}
},
"filter": {
"py":{
"type":"pinyin",
"keep_full_pinyin":false,
"keep_joined_full_pinyin":true,
"keep_original":true,
"limit_first_letter_length":16,
"remove_duplicated_term":true,
"none_chinese_pinyin_tokenize":false
}
}
}
},
"mappings": {
"properties": {
"name":{
"type": "text",
"analyzer": "my_analyzer",
"search_analyzer": "ik_smart"
}
}
}
}
然后重新插入之前的1,2文档
再次搜索如下
四、自动补全查询
对字段的要求
- 类型是completion类型
- 字段值是多词条的数组
completion suggester查询
示例
# 自动补全的索引库
PUT test2
{
"mappings": {
"properties": {
"title":{
"type": "completion"
}
}
}
}
# 示例数据
# 插入测试文档
POST /test2/_doc
{
"title":["Sony","WH-1000XM3"]
}
POST /test2/_doc
{
"title":["SK-II","PITERA"]
}
POST /test2/_doc
{
"title":["Nintendo","switch"]
}
# 自动补全查询
GET /test2/_search
{
"suggest": {
"titleSuggest": {
"text": "s",
"completion": {
"field": "title",
"skip_duplicates":true,
"size":10
}
}
}
}
效果