目录
自定义拼音分词器,根据拼音得到字段搜索文档数据
拼音分词器不会分词 ,而且也没有补充汉字,需要自定义分词器
我们的分词器要有两种:1.分词器analyzer;2.搜索的一个分词器,专门用于搜索的:search_analyzer(一般用中文ik)
分词器分为三部分:
指定分词配置
网站:/github.com/medcl/elasticsearch-analysis-pinyin
在创建索引库时,通过settings配置自定义分词器myanalyzer
包括tokenizer与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
}
}
}
}
}
拼音分词出现的问题(倒排索引):
当我们搜索出现同音词时,会出现不同词的访问
比如:你狮子和虱子进行分词->拼音+中文,而你进行搜索时,狮子分词出现拼音shizi,而你之前狮子与虱子的分词拼音都一样,所以就放在一起去了,id都在同一个词条上,所以一搜狮子就会出现虱子;
所以我们要分开使用,字段在创建倒排索引时使用my_analyzer分词器;字段在搜索时使用ik_smart分词器
搜索的时候如果你用了含有py的分词器,那么你搜的内容就会分词成英文,就会对着英文进行搜索,那么就会多一些不相关的内容;
自定义分词器用于字段创建时:包括ik+py
搜索时:用ik
Demo(基于拼音实现搜索)
对mappings中约束的字段使用分词器
#自定义拼音分词器my_analyzer
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"
}
}
}
}
然后我们进行测试,查看字段分词的结果(_analyze是用于分词测试的):
然后我们插入文档数据,进行查询
根据前面的约束可以知道,插入的文档数据name被进行分词(英文和中文都有),所以我们可以通过GET xxxx/_search query进行查询获取数据
注意:这里涉及上述搜索问题,如果搜索采用的是拼音分词器,那么我们query时候会将query的内容进行分词——>分成英文进行查询,而有些不相干的中文的英文是一样的,所以搜索的分词器应该设置为ik——>在创建倒排索引(mappings中约束的字段)时候进行设置
上述只是讲解了拼音分词器——>实现基于拼音对文档数据的搜索,下面是基于首字母的补全功能
completion suggester查询实现字段补全
作用:这种查询会以用户输入内容的开头的词条并返回
suggest相当于query类型,意思:补全查询
title_suggest相当于补全查询的名字
text关键字:意思就是以….开头可以进行自动补全查询
completion是补全查询的一种类型
field是能够补全查询的字段
skip_duplicates:跳过重复的
size:获取的结果数
跟普通查询一样:GET /索引/_search
只是里面加了suggest,然后字段的话,需要type+completion:指明可以补全
demo:
1.先设置文档中参与补全字段信息——>类型一定要是completion
2.然后POST数据即可
3.最后再自动补全查询,利用suggect查询
结果:
可以发现hits是空的,因为我们没有进行query,没有搜文档,而是自动补全查询
options中有自动补全的结果
这个text字段就是我们字段补全后的结果
案例:酒店数据自动补充
两个自定义分词器,一个text_anlyzer,一个是completion_analyzer:
意思就是一个是全文检索就是前面那个,自动补全就是后面那个;
添加新的字段约束suggestion,type=completion说明是支持补全的,分词器用的completion_analyzer说明是不支持分词的,直接字段拼音搜索
settings:定义酒店分词器
suggection里面封装了品牌信息和商圈信息(自动补全的内容)
按照首字母s查询,自动补全类型是completion,字段类型是suggestion
RestClient实现补全
GET /hotel/_search //准备请求
{
"suggest": {
"mySuggection": { //补全搜索名字
"text": "h", // 关键字
"completion": { //补全类型
"FIELD": "title", //补全字段
"skip_duplicates":true,
"size":10 //获取前十条结果
}
}
}
}
/**
* 自动补全查询
* @param prefix:搜索前缀
* @return:options中text内容
*/
@Override
public List<String> getSuggestions(String prefix) throws IOException {
SearchRequest request = new SearchRequest("hotel");
//2.准备DSL
request.source().suggest(new SuggestBuilder()
.addSuggestion("suggestions",
SuggestBuilders.completionSuggestion("suggection")
.prefix(prefix)
.skipDuplicates(true)
.size(10)));
//3.发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.处理响应
Suggest suggest = response.getSuggest();
CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
//4.2获取options
List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
//4.3遍历
ArrayList<String> result = new ArrayList<>(options.size());
for (CompletionSuggestion.Entry.Option option : options) {
String text = option.getText().toString();
result.add(text);
}
return result;
}
实现酒店搜索页面输入框的自动补全
今天的文章elasticsearch-自动补全分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/67615.html