ES实现自动补全查询
1.导入ES依赖
dependency>
< groupId> org. elasticsearch. client< / groupId>
< artifactId> elasticsearch- rest- high- level- client< / artifactId>
< / dependency>
2.ES建立索引库结构mapping
PUT / item
{
"settings" : {
"analysis" : {
"analyzer" : {
"text_anlyzer" : {
"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" : "ik_smart" ,
"copy_to" : "all"
} ,
"price" : {
"type" : "integer"
} ,
"stock" : {
"type" : "integer"
} ,
"image" : {
"type" : "keyword" ,
"index" : false
} ,
"category" : {
"type" : "keyword" ,
"copy_to" : "all"
} ,
"brand" : {
"type" : "keyword" ,
"copy_to" : "all"
} ,
"spec" : {
"type" : "text"
} ,
"sold" : {
"type" : "integer"
} ,
"commentCount" : {
"type" : "integer"
} ,
"isAD" : {
"type" : "integer"
} ,
"status" : {
"type" : "integer"
} ,
"createTime" : {
"type" : "date" ,
"format" : "yyyy-MM-dd HH:mm:ss"
} ,
"updateTime" : {
"type" : "date" ,
"format" : "yyyy-MM-dd HH:mm:ss"
} ,
"all" : {
"type" : "text" ,
"analyzer" : "ik_smart"
} ,
"suggestion" : {
"type" : "completion" ,
"analyzer" : "completion_analyzer"
}
}
}
}
3.创建ES实体类EsConstant
package com. hmall. search. constant ;
public interface EsConstant {
String ES_URL = "http://192.168.138.100:9200" ;
String ITEM_INDEX = "item" ;
String ITEM_MAPPING = " \"settings\": {\n" +
" \"analysis\": {\n" +
" \"analyzer\": {\n" +
" \"text_anlyzer\": {\n" +
" \"tokenizer\": \"ik_max_word\",\n" +
" \"filter\": \"py\"\n" +
" },\n" +
" \"completion_analyzer\": {\n" +
" \"tokenizer\": \"keyword\",\n" +
" \"filter\": \"py\"\n" +
" }\n" +
" },\n" +
" \"filter\": {\n" +
" \"py\": {\n" +
" \"type\": \"pinyin\",\n" +
" \"keep_full_pinyin\": false,\n" +
" \"keep_joined_full_pinyin\": true,\n" +
" \"keep_original\": true,\n" +
" \"limit_first_letter_length\": 16,\n" +
" \"remove_duplicated_term\": true,\n" +
" \"none_chinese_pinyin_tokenize\": false\n" +
" }\n" +
" }\n" +
" }\n" +
" },\n" +
" \"mappings\": {\n" +
" \"properties\": {\n" +
" \"id\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"name\":{\n" +
" \"type\":\"text\",\n" +
" \"analyzer\": \"ik_smart\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"price\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"stock\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"image\":{\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \"category\":{\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"brand\":{\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"spec\":{\n" +
" \"type\": \"text\"\n" +
" },\n" +
" \"sold\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"commentCount\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"isAD\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"status\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"createTime\":{\n" +
" \"type\": \"date\",\n" +
" \"format\": \"yyyy-MM-dd HH:mm:ss\"\n" +
" },\n" +
" \"updateTime\":{\n" +
" \"type\": \"date\",\n" +
" \"format\": \"yyyy-MM-dd HH:mm:ss\"\n" +
" },\n" +
" \"all\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_smart\"\n" +
" },\n" +
" \"suggestion\":{\n" +
" \"type\": \"completion\",\n" +
" \"analyzer\": \"completion_analyzer\"\n" +
" }\n" +
" }\n" +
" }" ;
}
4.ES配置类 客户端
package com. hmall. search. config ;
import com. hmall. search. constant. EsConstant ;
import org. apache. http. HttpHost ;
import org. elasticsearch. client. RestClient ;
import org. elasticsearch. client. RestHighLevelClient ;
import org. springframework. context. annotation. Bean ;
import org. springframework. context. annotation. Configuration ;
@Configuration
public class EsConfig {
@Bean
public RestHighLevelClient client ( ) {
return new RestHighLevelClient ( RestClient . builder ( HttpHost . create ( EsConstant . ES_URL) ) ) ;
}
}
5.写入实体类doc
5.1.创建一个list集合作为自动补全代码的字段
5.2. 把所需的补全字段添加进集合中(Constructor中)
package com. hmall. search. pojo ;
import lombok. AllArgsConstructor ;
import lombok. Data ;
import lombok. NoArgsConstructor ;
import java. util. ArrayList ;
import java. util. Date ;
import java. util. List ;
@Data
@NoArgsConstructor
public class ItemDoc {
private Long id;
private String name;
private Long price;
private Integer stock;
private String image;
private String category;
private String brand;
private String spec;
private Integer sold;
private Integer commentCount;
private Integer status;
private Boolean isAD;
private Date createTime;
private Date updateTime;
private List < String > suggestion = new ArrayList < > ( ) ;
public ItemDoc ( Long id, String name, Long price, Integer stock, String image, String category, String brand, String spec, Integer sold, Integer commentCount, Integer status, Boolean isAD, Date createTime, Date updateTime, List < String > suggestion) {
this . id = id;
this . name = name;
this . price = price;
this . stock = stock;
this . image = image;
this . category = category;
this . brand = brand;
this . spec = spec;
this . sold = sold;
this . commentCount = commentCount;
this . status = status;
this . isAD = isAD;
this . createTime = createTime;
this . updateTime = updateTime;
this . suggestion. add ( this . brand) ;
this . suggestion. add ( this . category) ;
}
}
6.业务实现代码
@Override
public List < String > suggestion ( String key) {
List < String > list = new ArrayList ( ) ;
try {
SearchRequest searchRequest = new SearchRequest ( EsConstant . ITEM_INDEX) ;
searchRequest. source ( ) . suggest ( new SuggestBuilder ( )
. addSuggestion ( "item_suggest" , new CompletionSuggestionBuilder ( "suggestion" )
. prefix ( key)
. skipDuplicates ( true )
. size ( 10 )
) ) ;
SearchResponse search = client. search ( searchRequest, RequestOptions . DEFAULT) ;
CompletionSuggestion completionSuggestion = search. getSuggest ( ) . getSuggestion ( "item_suggest" ) ;
List < CompletionSuggestion. Entry. Option > options = completionSuggestion. getOptions ( ) ;
for ( CompletionSuggestion. Entry. Option option : options) {
String text = option. getText ( ) . toString ( ) ;
list. add ( text) ;
}
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
return list;
}