一、实现思路
1.修改hotel索引库结构,设置自定义拼音分词器
2.修改索引库的name、all字段,使用自定义分词器
3.索引库添加一个新字段suggestion,类型为completion类型,使用自定义的分词器
4.给HotelDoc类添加suggestion字段,内容包含brand、business
5.重新导入数据到hotel库
二、参考文献
三、数据准备
1、新建索引库hotel2
增加字段suggestion
# 创建新的索引库2
PUT /hotel2
{
"settings":{
"analysis": {
"analyzer": {
"text_analyzer":{
"tokenizer": "ik_max_word",
"filter":"py"
},
"completion_analyzer":{
"tokenizer": "keyword",
"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": {
"id":{
"type": "keyword"
},
"name":{
"type": "text",
"analyzer": "text_analyzer",
"search_analyzer": "ik_smart",
"copy_to": "all"
},
"address":{
"type": "keyword",
"index": false
},
"price":{
"type":"keyword"
},
"score":{
"type":"keyword"
},
"brand":{
"type":"keyword",
"copy_to": "all"
},
"city":{
"type":"keyword"
},
"starName":{
"type":"keyword"
},
"business":{
"type":"keyword",
"copy_to": "all"
},
"location":{
"type":"geo_point"
},
"pic":{
"type":"keyword",
"index": false
},
"all":{
"type": "text",
"analyzer": "text_analyzer",
"search_analyzer": "ik_smart"
},
"suggestion":{
"type": "completion",
"analyzer": "completion_analyzer"
}
}
}
}
2、重新导入数据
3、测试自动补全
# 自动补全查询
GET /hotel2/_search
{
"suggest": {
"suggestions": {
"text": "s",
"completion": {
"field": "suggestion",
"skip_duplicates":true,
"size":10
}
}
}
}
四、RestAPI实现自动补全
1、先看请求参数构造的API
2、执行测试方法
testSuggest()
/**
* 测试自动补全
* @throws IOException
*/
@Test
void testSuggest() throws IOException {
// 1. 准备Request
SearchRequest request = new SearchRequest(INDEX);
// 2. 准备DSL
request.source().suggest(new SuggestBuilder().addSuggestion(
"suggestions",
SuggestBuilders
.completionSuggestion("suggestion")
.prefix("h")
.skipDuplicates(true)
.size(10)
));
// 3. 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4.解析响应
//得到响应结果
// System.out.println(response);
Suggest suggest = response.getSuggest();
// 4.1 根据补全查询名称,获取补全结果
CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
// 4.2 获取options
List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
// 4.3 遍历
for(CompletionSuggestion.Entry.Option option : options){
String text = option.getText().toString();
System.out.println(text);
}
}
3、解析结果
五、实战案例
1、前端页面请求
2、代码
// controller
/**
* 自动补全
* @param prefix
* @return
*/
@GetMapping("/suggestion")
public List<String> getFilters(@RequestParam("key") String prefix){
return hotelService.getSuggestions(prefix);
}
...
...
// service
@Override
public List<String> getSuggestions(String prefix) {
try{
// 1. 准备Request
SearchRequest request = new SearchRequest(INDEX);
// 2. 准备DSL
request.source().suggest(new SuggestBuilder().addSuggestion(
"suggestions",
SuggestBuilders
.completionSuggestion("suggestion")
.prefix(prefix)
.skipDuplicates(true)
.size(10)
));
// 3. 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 4.解析响应
//得到响应结果
// System.out.println(response);
Suggest suggest = response.getSuggest();
// 4.1 根据补全查询名称,获取补全结果
CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
// 4.2 获取options
List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
// 4.3 遍历
List<String> list = new ArrayList<>(options.size());
for(CompletionSuggestion.Entry.Option option : options){
String text = option.getText().toString();
System.out.println(text);
list.add(text);
}
return list;
}catch (IOException e){
throw new RuntimeException(e);
}
}