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的很多天"

中英文的分词都具有了。

完整版索引创建+分词器

但是拼音分词器适合在创建倒排索引的时候使用,不能在搜索的时候使用。假如遇见同音不同字的,搜索时是按照中文搜索的,那么所有同音的就会全都被搜索出来,会出问题。!

如下:在文档中新增狮子、虱子后,查询时中文带狮子,但是因为查询时也同时使用了拼音分词器,所以虱子也会被查询

所以,我们可以在创建索引时使用ikpinyin分词器,但是查询时还是要根据用户输入的是中文还是拼音去选择分词器。

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从入门到精通--第七话(自动补全拼音分词器自定义分词数据同步方案)的主要内容,如果未能解决你的问题,请参考以下文章

嵌入式Linux从入门到精通之第七节:GTK+概述

Elasticsearch7从入门到精通(简介部署原理开发ELK)

Elasticsearch教程-从入门到精通(转)

《从入门到精通云服务器》第七讲—IAASPAASSAAS

编程不良人--ElasticSearch从入门到精通--- 狗剩学习笔记

Elasticsearch 7.x从入门到精通