零、本文纲要
- 一、自动补全
- 二、使用拼音分词
- 三、自定义分词器
1、分词器的组成
2、使用自定义分词器 - 四、ES自动补全
1、completion suggester查询
2、使用DSL语句进行查询
3、RestClient实现自动补全
tips:Ctrl + F快速定位所需内容进行阅读吧。
一、自动补全
当用户在搜索框输入字符时,提示出与该字符有关的搜索项,如图:
二、使用拼音分词
开源的拼音分词插件:Pinyin Analysis plugin。
① 下载解压
② 上传到plugin目录
/var/lib/docker/volumes/es-plugins/_data
查看elasticsearch的plugins目录位置,命令如下:
docker volume inspect es-plugins
显示结果:
[
{
"CreatedAt": "2022-04-04T17:07:34+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/es-plugins/_data",
"Name": "es-plugins",
"Options": null,
"Scope": "local"
}
]
- ③ 重启elasticsearch
docker restart es
三、自定义分词器
1、分词器的组成
- ①
character filters
:在tokenizer之前对文本进行处理,例如删除字符
、替换字符
; - ②
tokenizer
:将文本按照一定的规则切割成词条(term),例如keyword不分词
、还有ik_smart
; - ③
tokenizer filter
:将tokenizer输出的词条做进一步处理,例如大小写转换
、同义词处理
、拼音处理
等。
2、使用自定义分词器
- ① 直接使用的情形
如果直接使用分词器创建索引库,会创建大量的单字拼音索引,浪费空间,如下:
- ② 配置后,同时使用自定义分词器创建倒排索引和搜索
使用pinyin分词器创建倒排索引,会导致shizi下同时存在狮子和虱子;此时,我们去搜素时,分词器又会分词出shizi,得到虱子的数据,不符合预期,如下:
- ③ 配合ik分词器配置后使用
# 自定义分词器
PUT /test
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": { //自定义分词器
"tokenizer": "ik_max_word", //先ik
"filter": "py" //后py
}
},
"filter": { //配置pinyin分词器
"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"
}
}
}
}
四、ES自动补全
官方文档:ES completion suggester。
1、completion suggester查询
ES提供了Completion Suggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。
- completion suggester查询的约束:
Ⅰ 参与补全查询的字段必须是completion类型;
Ⅱ 字段的内容一般是用来补全的多个词条形成的数组。
2、使用DSL语句进行查询
实例:
# 自动补全索引库
PUT /test2
{
"mappings": {
"properties": {
"title": {
"type": "completion"
}
}
}
}
POST /test2/_doc
{
"title": ["Sony", "WH-1000XM4"]
}
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 //获取前10条结果
}
}
}
}
3、RestClient实现自动补全
- ① 准备DSL查询
// 1. 获取请求对象
SearchRequest request = new SearchRequest("hotel");
// 2. 准备DSL语句
request.source().suggest(new SuggestBuilder().addSuggestion(
"hotelSuggest",
SuggestBuilders.completionSuggestion("suggestion")
.prefix("sh")
.skipDuplicates(true)
.size(10)
));
// 3. 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
- ② 解析结果数据
// 4. 解析响应
Suggest suggest = response.getSuggest();
// 4.1 根据补全查询名称,获取补全结果
CompletionSuggestion suggestions = suggest.getSuggestion("hotelSuggest");
// 4.2 获取options
List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
// 4.3 遍历
for (CompletionSuggestion.Entry.Option option : options) {
String text = option.getText().toString();
// 5. 输出结果
System.out.println(text);
}
五、结尾
以上即为自动补全的全部内容,感谢阅读。