7.2 自动补全
一、拼音分词器
安装拼音分词器
地址:https://github.com/medcl/elasticsearch-analysis-pinyin
解压
上传(es目录下的plugin文件夹中)
重启
测试
二、自定义分词器
问题
没有对内容分词
每个子偶读解析成拼音
没有汉字
ES中分词器(analyzer)的组成包含三部分:
character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符
tokenizer:将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart
tokenizer filter:将tokenizer输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理等
自定义分词器:
创建索引库时,通过settings来配置自定义的analyzer(分词):
PUT /test { "settings": { // 索引库配置 "analysis": { // 进行分析 "analyzer": { // 制定分词器 "my_analyzer": { // 制定的分词器名称 "tokenizer": "ik_max_word", // 指定tokenizer,为ik分词器分词 "filter": "pinyin" // 指定filter,转拼音 } } } } }备注:创建索引库时进行自定义,只对当前索引库有效
上面的方式设置之后,拼音分词器还会对if分词器分词后的内容进行原规则拆分,因此,对拼音分词器还要进行再次定制
PUT /test { "settings": { // 索引库配置 "analysis": { // 进行分析 "analyzer": { // 制定分词器 "my_analyzer": { // 制定的分词器名称 "tokenizer": "ik_max_word", // 指定tokenizer,为ik分词器分词 "filter": "py" // 指定filter,到自己制定的分词器类型 } }, "filter": { // 自定义tokenizer filter "py": { // 自定义过滤器名称 "type": "pinyin", // 过滤器类型,这里是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": ...... }备注:过滤器中,py下面的配置是根据下载地址中给的可配置参数,进行的拼音分词器设置
定义后的使用方式
在定义索引库时候,mapping中定义分词器使用自定义分词器
定义索引库的mapping必须与settings同时存在
注意:
拼音分词器适合在穿件倒排索引时候使用,但不能在搜索的时候使用
解决办法:
在创建倒排索引库的时候,从制定两个分词器,一个创建时候的分词器,一个查询时候的分词器
PUT /test { "settings": { // 索引库配置 "analysis": { // 进行分析 "analyzer": { // 制定分词器 "my_analyzer": { // 制定的分词器名称 "tokenizer": "ik_max_word", // 指定tokenizer,为ik分词器分词 "filter": "py" // 指定filter,到自己制定的分词器类型 } }, "filter": { // 自定义tokenizer filter "py": { // 自定义过滤器名称 "type": "pinyin", // 过滤器类型,这里是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": { "字段名": { "type": "text", "analyzer": "my_analyzer", "search_analyzer": "ik_smart" } } } }
三、自动补全查询
ES提供了Completion Suggester查询来实现自动补全功能。这个查询会匹配以用户输入内容开头的词条并返回。为了提高补全查询的效率,对于文档中字段的类型有一些约束:
参与补全查询的字段必须是
completion类型(创建索引库的时候定义)字段的内容一般是用来补全的多个词条形成的数组
查询语法:
GET /索引库名称/_search { "suggest": { "title_suggest": { "text": "关键字", "completion": { "fiels": "补全查询的字段", "skip_duplicates": true, // 跳过重复的 "size": 10 // 获取前10条数据 } } } }RestAPI实现自动补全
@Test public void suggestTest() throws IOException { // 准备request SearchRequest request = new SearchRequest("hotel"); // 准备DSL request.source().suggest(new SuggestBuilder().addSuggestion( "suggestions", // 自定义的补全查询名称 SuggestBuilders.completionSuggestion("suggestion") // 补全字段 .prefix("h") // 关键字 .skipDuplicates(true) // 不重复 .size(10) // 只取10条 )); // 发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); System.out.println(response); // 解析结果 Suggest suggest = response.getSuggest(); // 根据名称获取补全结果 CompletionSuggestion suggestions = suggest.getSuggestion("suggestions"); // 获取列表 List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions(); // 逐条拆分解析 for (CompletionSuggestion.Entry.Option option : options) { String s = option.getText().toString(); System.out.println(s); } }
最后更新于
这有帮助吗?