ElasticSearch从入门到精通--第七话(自动补全拼音分词器自定义分词数据同步方案)
Posted 鸢尾の
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch从入门到精通--第七话(自动补全拼音分词器自定义分词数据同步方案)相关的知识,希望对你有一定的参考价值。
ElasticSearch从入门到精通–第七话(自动补全、拼音分词器、自定义分词、数据同步方案)
使用拼音分词
可以引入elasticsearch的拼音分词插件,地址:https://github.com/medcl/elasticsearch-analysis-pinyin
-
下载后,将包上传至服务器后,解压缩
unzip -d py elasticsearch-analysis-pinyin-7.12.1.zip
-
将压缩后的目录放入
es的plugins中即可
,我这边是docker的数据卷,直接放入就行cp -r py/ /var/lib/docker/volumes/es-plugins/_data
-
重启es服务
docker restart es
进入kibana控制台,使用拼音分词器看下结果
POST
请求/analyze
"analyzer": "pinyin",
"text": "学习es的很多天"
是按照拼音进行分词的。
自定义分词器
实现方式就是先走ik分词器
,然后再走pinyin分词器
进行拼音处理。
我们可以在创建索引库时,通过settings来配置自定义的analyzer
(分词器)
实例:
PUT /test
"settings":
"analysis":
"analyzer":
"my_analyzer": // 自定义 my_analyzer分词器
"tokenizer": "ik_max_word", // 先经过ik处理
"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" // 使用自定义分词器
测试
POST /test/_analyze
"analyzer": "my_analyzer",
"text": "学习es的很多天"
中英文的分词都具有了。
完整版索引创建+分词器
但是拼音分词器适合在创建倒排索引的时候使用,不能在搜索的时候使用。假如遇见同音不同字的,搜索时是按照中文搜索的,那么所有同音的就会全都被搜索出来,会出问题。!
如下:在文档中新增狮子、虱子
后,查询时中文带狮子
,但是因为查询时也同时使用了拼音分词器,所以虱子也会被查询
所以,我们可以在创建索引时使用ik
和pinyin
分词器,但是查询时还是要根据用户输入的是中文还是拼音去选择分词器。
DELETE /test
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" // 查询时使用ik分词器
自动补全
es提供了Completion Suggester查询来实现自动补全功能。这个查询会匹配用户输入内容开头的词条并且返回。条件是:参与补全查询的字段必须设置为completion类型,字段的内容一般是用来补全的多个词条形成的数组
查询时不再用query,而是使用的suggest
示例:
DELETE test
PUT test
"mappings":
"properties":
"title":
"type": "completion"
// 插入数据
POST test/_doc
"title": ["Sony", "WH-1000XM3"]
POST test/_doc
"title": ["SK-II", "PITERA"]
POST test/_doc
"title": ["Nintendo", "switch"]
查询
GET /test/_search
"suggest":
"title_suggest": // 自定义查询名
"text": "s", // 关键字
"completion":
"field": "title", // 补全字段
"skip_duplicates": true, // 跳过重复的
"size": 10 // 获取前10条结果
完整版demo
PUT /hotel
"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": "text_anlyzer",
"search_analyzer": "ik_smart",
"copy_to": "all"
,
"address":
"type": "keyword",
"index": false
,
"price":
"type": "integer"
,
"score":
"type": "integer"
,
"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_anlyzer",
"search_analyzer": "ik_smart"
,
"suggestion":
"type": "completion",
"analyzer": "completion_analyzer"
RestAPI实现自动补全+结果处理
public class ESTEST_API_Query
public static void main(String[] args) throws IOException
// 创建es客户端,指定ip和端口
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("192.168.1.40", 9200, "http"))
);
SearchRequest request = new SearchRequest("hotel");
request.source().suggest(new SuggestBuilder().addSuggestion(
"mySuggestion",
SuggestBuilders
.completionSuggestion("title")
.prefix("h") // 用户输入的关键字
.skipDuplicates(true) // 跳过重复
.size(10) // 取10条
));
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
client.close();
结果处理
数据同步
es中很多数据都是来自mysql的,因为mysql数据发生改变时,es必须要跟着改变数据,就是es和mysql之间的数据同步
.
实现简单,粗暴。但是业务耦合度较高。
低耦合,实现难度一般,需要依赖mq的可靠性
以上是关于ElasticSearch从入门到精通--第七话(自动补全拼音分词器自定义分词数据同步方案)的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch7从入门到精通(简介部署原理开发ELK)